package com.itlong.cloud.controller.current;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.*;
import com.itlong.cloud.POJO.DTO.common.PadFaceSyncDataDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateBusinessChargeDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateSavePushInfoDTO;
import com.itlong.cloud.POJO.DTO.property.IotCloudEntranceStateDTO;
import com.itlong.cloud.POJO.DTO.property.IotCloudIntercomStateDTO;
import com.itlong.cloud.POJO.DTO.property.PadUserAuthPushDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.*;
import com.itlong.cloud.POJO.VO.operate.OperateActivitiesGetPageVO;
import com.itlong.cloud.POJO.VO.operate.OperateAppHomePageGetPageVO;
import com.itlong.cloud.POJO.VO.operate.OperateFaceApplyInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperatePropertyInformationGetVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.annotation.UnParamEncrypt;
import com.itlong.cloud.common.network.ITCPServiceClient;
import com.itlong.cloud.common.network.tcp.mina.IMinaServiceClient;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.ErrorCode;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode_en.AppErrorCodeEnumEN;
import com.itlong.cloud.enumerate.ecode_en.BaseErrorCodeEnumEN;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.app.IAppVisitorPassCodeRecordServiceClient;
import com.itlong.cloud.equip.commons.ICloudEntranceServiceClient;
import com.itlong.cloud.equip.operate.IOperateAddressManageServiceClient;
import com.itlong.cloud.equip.property.ICloudIntercomServiceClient;
import com.itlong.cloud.equip.property.IPadFaceSyncDataServiceClient;
import com.itlong.cloud.iottp.IIotBaiduFaceServiceClient;
import com.itlong.cloud.iottp.IIotServerServiceClient;
import com.itlong.cloud.noncore.app.IAppAppPublishInfoServiceClient;
import com.itlong.cloud.noncore.operate.IOperateAppFunctionInfoServiceClient;
import com.itlong.cloud.noncore.operate.IOperateAppHomePageServiceClient;
import com.itlong.cloud.paymenthub.IOperateBusinessChargeServiceClient;
import com.itlong.cloud.project.app.IAppProjectAddressServiceClient;
import com.itlong.cloud.project.app.IAppProjectServiceClient;
import com.itlong.cloud.project.operate.IOperateActivitiesServiceClient;
import com.itlong.cloud.project.operate.IOperateFaceApplyServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.project.operate.IOperatePushInfoServiceClient;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppHomeServiceClient;
import com.itlong.cloud.user.app.IAppPadFaceServiceClient;
import com.itlong.cloud.user.app.IAppRegisterServiceClient;
import com.itlong.cloud.user.app.IAppUserInfoCacheServiceClient;
import com.itlong.cloud.user.property.IPropertyHouseHoldInfoServiceClient;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <desc>
 *     新版APP首页版块控制器
 * </desc>
 *
 * @create  2017/9/19
 */
@RestController
@RequestMapping("/home")
@RefreshScope
public class AppHomeController extends BaseController{

    private static final Logger LOG = LoggerFactory.getLogger(AppHomeController.class);

    @Value("${" + PlatformConstants.APP_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String APP_REQUEST_PARAMS_ENCRYPT_KEY;

    @Value("${" + PlatformConstants.APP_USER_TOKEN_KEY + "}")
    public String APP_USER_TOKEN_KEY;

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;
    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;
    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;
    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;
    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Value("${" + PlatformConstants.PROPERTYMANAGE_WEB_URL + "}")
    public String PROPERTY_MANAGE_WEB_URL;

    @Autowired
    private IOperatePushInfoServiceClient iOperatePushInfoServiceClient;

    @Autowired
    private IPropertyHouseHoldInfoServiceClient iPropertyHouseHoldInfoServiceClient;

    @Autowired
    private IMinaServiceClient iMinaServiceClient;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    IAppHomeServiceClient iAppHomeServiceClient;

    @Autowired
    IAppProjectAddressServiceClient iAppProjectAddressServiceClient;

    @Autowired
    IAppProjectServiceClient iAppProjectServiceClient;

    @Autowired
    IAppAppPublishInfoServiceClient iAppAppPublishInfoServiceClient;

    @Autowired
    IAppUserInfoCacheServiceClient userCache;

    @Autowired
    IAppRegisterServiceClient iAppRegisterServiceClient;

    @Autowired
    IAppDeviceServiceClient iAppDeviceServiceClient;

    @Autowired
    IAppVisitorPassCodeRecordServiceClient iAppVisitorPassCodeRecordServiceClient;

    @Autowired
    IOperateAppFunctionInfoServiceClient iOperateAppFunctionInfoServiceClient;

    //地址管理
    @Autowired
    IOperateAddressManageServiceClient iOperateAddressManageServiceClient;

    @Autowired
    ITCPServiceClient itcpServiceClient;

    @Autowired
    ICloudEntranceServiceClient iCloudEntranceServiceClient;

    @Autowired
    IIotServerServiceClient iIotServerServiceClient;

    @Autowired
    IOperateFaceApplyServiceClient iOperateFaceApplyServiceClient;

    @Autowired
    IIotBaiduFaceServiceClient iIotBaiduFaceServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    @Autowired
    IPadFaceSyncDataServiceClient iPadFaceSyncDataServiceClient;

    @Autowired
    IAppPadFaceServiceClient iAppPadFaceServiceClient;

    @Autowired
    IOperateBusinessChargeServiceClient iOperateBusinessChargeServiceClient;

    @Autowired
    IOperateAppHomePageServiceClient iOperateAppHomePageServiceClient;

    @Autowired
    IOperateActivitiesServiceClient iOperateActivitiesServiceClient;

    @Autowired
    ICloudIntercomServiceClient iCloudIntercomServiceClient;

    /**
     *  <desc>
     *      获取所有城市信息列表,首字母分组及城市ID与城市名称
     *  </desc>
     * @return
     *  @author cuiduanwu
     * @createDate 2017/9/28
     *  @author cuiduanwu
     */
    @RequestMapping(path = "/getCitys",method = RequestMethod.POST)
    @ResponseBody
    public Object getCitys() throws  Exception{
        try {
//            List<AppProjectAddressVO> projectAddressList = iAppProjectAddressServiceClient.getAllUsedCityInitials();
            AppNewProjectAddressVO projectAddress = iAppProjectAddressServiceClient.getNewAllUsedCityInitials();

            return  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),projectAddress);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块_城市列表】获取城市列表失败",e);
        }
    }


    /**
     * <desc>
     *      根据城市名称获取城市id。
     * <desc/>
     *
     * @param
     * @return
     * @author Jiaqi.X
     * @createDate 2020/05/28
     */
    @RequestMapping(path = "/getCityId",method = RequestMethod.POST)
    @ResponseBody
    public Object getCityId(String city,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            city = request.getAttribute("city") == null ? null : request.getAttribute("city").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("city",city);
            params.put("createTime",createTime);
            params.put("language",language);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode());
            }
            Map<String,Object> result = new HashMap<>();
            result.put("cityId",iAppProjectServiceClient.getCityIdByCityName(city));
            messageVO = new MessageVO(BaseErrorCodeEnumEN.SUCCESS.getErrorCode(),result);
        }catch (Exception e){
            throw new DataAccessException("【APP首页】根据城市名称获取城市id失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取国外国家列表。
     * <desc/>
     *
     * @param
     * @return
     * @author shengen.T
     * @createDate 2018-01-03
     */
    @RequestMapping(path = "/getCountrys",method = RequestMethod.POST)
    @ResponseBody
    public Object getCountry(String language){
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            List<AppForeignProjectAddressVO> countryList =iAppProjectAddressServiceClient.getAllCountryInitials();
            messageVO = new MessageVO(BaseErrorCodeEnumEN.SUCCESS.getErrorCode(),countryList);
        }catch (Exception e){
            throw new DataAccessException("【APP首页】获取国家列表信息失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      根据国家ID获取该国家项目信息列表。
     * <desc/>
     *
     * @param  countryId
     * @param  pageNo
     * @param  pageSize
     * @return
     * @author shengen.T
     * @createDate 2018-01-03
     */
    @RequestMapping(path = "/getProjectsInCountry",method = RequestMethod.POST)
    @ResponseBody
    public Object getProjectsInCountry(String token,String countryId,String pageNo,String pageSize,String createTime,String sign,String language ){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                countryId = request.getAttribute("countryId") == null ? null : request.getAttribute("countryId").toString();
                pageNo = request.getAttribute("pageNo") == null ? null : request.getAttribute("pageNo").toString();
                pageSize = request.getAttribute("pageSize") == null ? null : request.getAttribute("pageSize").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("countryId",countryId);
            params.put("pageNo",pageNo);//参与验签，不分页
            params.put("pageSize",pageSize);//参与验签，不分页
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(countryId)||StringUtils.isBlank(pageNo)||StringUtils.isBlank(pageSize)||StringUtils.isBlank(createTime)){
                    return new MessageVO(BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(countryId)||StringUtils.isBlank(pageNo)||StringUtils.isBlank(pageSize)||StringUtils.isBlank(createTime)){
                    return new MessageVO(BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode());
                }
            }
            Page<Map<String,Object>> page = iAppProjectServiceClient.getProjectsInCountry(countryId,pageNo,pageSize);
            JSONObject js = new JSONObject();
            js.put("projects",page.getRows());
            messageVO =  new MessageVO(BaseErrorCodeEnumEN.SUCCESS.getErrorCode(),js);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块_项目信息列表】获取项目信息列表失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      根据城市ID获取启用状态的项目信息（项目编号与项目名称）
     * </desc>
     * @param cityId 城市ID
     * @return
     * @createDate 2017/9/29
     *  @author cuiduanwu
     */
    @RequestMapping(path = "/getProjectsInCityByCityId",method = RequestMethod.POST)
    @ResponseBody
    public Object getProjectsInCityByCityId(String cityId,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                cityId = request.getAttribute("cityId") == null ? null : request.getAttribute("cityId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("cityId",cityId);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(cityId)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(cityId)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }
            }
            JSONObject js = new JSONObject();
            List<AppProjectBuildVO> list = iAppProjectServiceClient.getNewProjectsInCity(cityId);
            js.put("projects",list);
            messageVO =  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),js);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块_项目信息列表】获取项目信息列表失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      根据楼栋ID获取启用状态的项目信息（项目编号与项目名称）
     * </desc>
     * @param buildId 楼栋ID
     * @return
     * @createDate 2017/9/29
     *  @author cuiduanwu
     */
    @RequestMapping(path = "/getProjectsInCityByBuildId",method = RequestMethod.POST)
    @ResponseBody
    public Object getProjectsInCityByBuildId(String buildId,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                buildId = request.getAttribute("buildId") == null ? null : request.getAttribute("buildId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("buildId",buildId);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(buildId)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(buildId)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }
            }
            JSONObject js = new JSONObject();
            List<AppProjectRoomVO> list = iAppProjectServiceClient.getNewProjectsUnit(buildId);
            js.put("projects",list);
            messageVO =  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),js);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块_项目信息列表】获取项目信息列表失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      根据项目编号获取启用状态的楼栋信息
     * </desc>
     * @param projectId 项目编号
     * @param pageNo
     * @param pageSize
     * @return
     * @createDate 2017/9/29
     *  @author cuiduanwu
     */
    @RequestMapping(path = "/getBuildList",method = RequestMethod.POST)
    @ResponseBody
    public Object getBuildsInProject(String projectId,String pageNo,String pageSize,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                pageNo = request.getAttribute("pageNo") == null ? null : request.getAttribute("pageNo").toString();
                pageSize = request.getAttribute("pageSize") == null ? null : request.getAttribute("pageSize").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("pageNo",pageNo);//参与验签，不分页
            params.put("pageSize",pageSize);//参与验签，不分页
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(projectId)||StringUtils.isBlank(pageNo)||StringUtils.isBlank(pageSize)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (!projectId.matches("[0-9]{8}")){
                    LOG.info("【APP_首页版块_获取楼栋信息】项目编号非法"+projectId);
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode():AppErrorCodeEnumEN.PROJECT_NOT_MATCH.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(projectId)||StringUtils.isBlank(pageNo)||StringUtils.isBlank(pageSize)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (!projectId.matches("[0-9]{8}")){
                    LOG.info("【APP_首页版块_获取楼栋信息】项目编号非法"+projectId);
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode():AppErrorCodeEnumEN.PROJECT_NOT_MATCH.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }

            Page<PropertyProjectBuildSimpleInfoVO> page = iAppProjectServiceClient.getBuildsInProject(projectId,pageNo,pageSize);
            JSONObject js = new JSONObject();
            js.put("builds",page.getRows());
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO =  new MessageVO(errorCode,js);
        }catch (Exception e){
            throw  new DataAccessException("【APP_首页版块_项目下楼栋信息列表】获取项目下楼栋信息列表失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      根据楼栋ID获取启用状态的单元信息
     * </desc>
     * @param buildId  楼栋ID
     * @return
     * @createDate 2017/9/30
     * @author cuiduanwu
     */
    @RequestMapping(path = "/getUnitList",method = RequestMethod.POST)
    @ResponseBody
    public Object getUnitsInBuild(String buildId,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                buildId = request.getAttribute("buildId") == null ? null : request.getAttribute("buildId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("buildId",buildId);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(buildId)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(buildId)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }

            Page<PropertyProjectUnitSimpleInfoVO> page = iAppProjectServiceClient.getUnitsInBuild(buildId);
            JSONObject js = new JSONObject();
            js.put("units",page.getRows());
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,js);
        }catch (Exception e){
            throw  new DataAccessException("【APP_首页版块_楼栋下单元信息列表】获取项目楼栋下单元信息列表失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      根据单元ID获取启用状态的房间信息
     * </desc>
     * @param unitId  单元ID
     * @return
     * @createDate 2017/10/9
     * @author cuiduanwu
     */
    @RequestMapping(path = "/getRoomList",method = RequestMethod.POST)
    @ResponseBody
    public Object getRoomsInUnit(String unitId,String pageNo,String pageSize,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                unitId = request.getAttribute("unitId") == null ? null : request.getAttribute("unitId").toString();
                pageNo = request.getAttribute("pageNo") == null ? null : request.getAttribute("pageNo").toString();
                pageSize = request.getAttribute("pageSize") == null ? null : request.getAttribute("pageSize").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("unitId",unitId);
            params.put("pageNo",pageNo);//参与验签，不分页
            params.put("pageSize",pageSize);//参与验签，不分页
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(unitId)||StringUtils.isBlank(pageNo)||StringUtils.isBlank(pageSize)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(unitId)||StringUtils.isBlank(pageNo)||StringUtils.isBlank(pageSize)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }

            Page<PropertyProjectRoomSimpleInfoVO> page = iAppProjectServiceClient.getRoomsInUnit(unitId, pageNo, pageSize);
            JSONObject js = new JSONObject();
            js.put("rooms",page.getRows());
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,js);
        }catch (Exception e){
            throw  new DataAccessException("【APP_首页版块_单元下房间信息列表】获取单元下房间信息列表失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      APP端_首页版块根据项目编号、楼栋ID、单元ID、房间ID获取房间业主的电话号码
     * </desc>
     * @param roomId 房间ID
     * @return
     * @createDate 2017/9/30
     * @author cuiduanwu
     */
    @RequestMapping(path = "/getOwnerPhoneNumber",method = RequestMethod.POST)
    @ResponseBody
    public Object getOwnerPhoneNumber(String roomId,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                roomId = request.getAttribute("roomId") == null ? null : request.getAttribute("roomId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("roomId",roomId);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(roomId)||StringUtils.isBlank(createTime)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(roomId)||StringUtils.isBlank(createTime)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }
            }
            String ownerPhoneNo = iAppHomeServiceClient.getOwnerPhoneNumber(roomId);
            String roomType = iAppHomeServiceClient.getRoomTypeByroomId(roomId);
            List<Map<String, Object>> roleList = iAppProjectServiceClient.getProjectRoleList(roomId);
            JSONObject js = new JSONObject();
            js.put("ownerPhoneNumber",ownerPhoneNo);
            js.put("roomType",roomType);
            js.put("roleList", roleList);
            messageVO =  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),js);
        }catch (Exception e){
            throw  new DataAccessException("【APP_首页版块_房间业主的电话号码】获取房间业主的电话号码失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *     APP端_首页版块,用户提交房屋认证申请
     * </desc>
     * @param token 申请人用户Token
     * @param appApplyRoomCertificationDTO 用户提交申请房屋认证数据
     * @return
     * @createDate 2017/9/30
     * @author cuiduanwu
     */
    @LoggerInfo(operateDesc = LogDescConstant.ROOM_APPLY_CERTIFICATION)
    @RequestMapping(path = "/applyCertification",method = RequestMethod.POST)
    @ResponseBody
    public Object applyRoomCertification(String token,AppApplyRoomCertificationDTO appApplyRoomCertificationDTO,String createTime,String sign,String language){
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                appApplyRoomCertificationDTO = HttpProtocolUtil.parseRequestParamToDTO(AppApplyRoomCertificationDTO.class, request);
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("roomId",appApplyRoomCertificationDTO.getRoomId());
            params.put("applyHouseType",appApplyRoomCertificationDTO.getApplyHouseType());
            params.put("ownerPhoneNo",appApplyRoomCertificationDTO.getOwnerPhoneNo());
            params.put("smsCode",appApplyRoomCertificationDTO.getSmsCode());
            params.put("certificationType", appApplyRoomCertificationDTO.getCertificationType());
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(appApplyRoomCertificationDTO.getRoomId())||StringUtils.isBlank(appApplyRoomCertificationDTO.getApplyHouseType())){
                    //房间ID与申请身份不可为空
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.NOT_PARAM.getErrorCode():AppErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return  new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(appApplyRoomCertificationDTO.getRoomId())||StringUtils.isBlank(appApplyRoomCertificationDTO.getApplyHouseType())){
                    //房间ID与申请身份不可为空
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.NOT_PARAM.getErrorCode():AppErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return  new MessageVO(errorCode);
                }
            }
            boolean smsSuccess = false;
            String userId = UserTokenUtil.newAPPTokenDecrypt(token, APP_USER_TOKEN_KEY);
            //验证是是否业主认证，认证方式为空时为兼容旧版本不校验
            if(!"1".equals(appApplyRoomCertificationDTO.getApplyHouseType())
                    && appApplyRoomCertificationDTO.getCertificationType() != null
                    && RoomCertificateTypeEnum.HOUSER_CERTIFIFATE.getType().toString().equals(appApplyRoomCertificationDTO.getCertificationType())){
                //非业主时业主手机号与验证码不可为空
                if (StringUtils.isBlank(appApplyRoomCertificationDTO.getSmsCode())){
                    return  new MessageVO(AppErrorCodeEnum.NOT_PARAM.getErrorCode());
                }else {
                    //非业主时核对短信验证码是否正确
                    String smsCodeCache = redisService.get(RedisConstant.REDIS_SMS_CODE+appApplyRoomCertificationDTO.getOwnerPhoneNo());
                    if (!appApplyRoomCertificationDTO.getSmsCode().equals(smsCodeCache)){
                        return new MessageVO(AppErrorCodeEnum.SMSCODE_ERR.getErrorCode());
                    } else if (StringUtils.isBlank(smsCodeCache)){
                        return new MessageVO(AppErrorCodeEnum.SMSCODE_EXPIRE.getErrorCode());
                    }
                    smsSuccess = true;
                }
                if (!NumberHandlerUtil.isPhoneNo(appApplyRoomCertificationDTO.getOwnerPhoneNo())){
                    return new MessageVO(AppErrorCodeEnum.PHONE_NOT_MATCH.getErrorCode());
                }
            }

            PropertyProjectRoomInfoVO roomInfoPO = iAppProjectServiceClient.getRoomById(appApplyRoomCertificationDTO.getRoomId());
            //检查房间不存在或房间已被删除
            if (roomInfoPO == null||(roomInfoPO != null&&1!=roomInfoPO.getStatus())){
                return  new MessageVO(AppErrorCodeEnum.ROOM_NOT_EXIST.getErrorCode());
            }
            appApplyRoomCertificationDTO.setUserId(userId);
            appApplyRoomCertificationDTO.setProjectId(roomInfoPO.getProjectId());
            appApplyRoomCertificationDTO.setBuildId(roomInfoPO.getBuildId());
            appApplyRoomCertificationDTO.setUnitId(roomInfoPO.getUnitId());
            appApplyRoomCertificationDTO.setRoomNum(roomInfoPO.getRoomNum());
            appApplyRoomCertificationDTO.setInstructionType(16);
            appApplyRoomCertificationDTO.setSourceSystem(0);
            MessageVO messageVO = iAppHomeServiceClient.applyRoomCertification(appApplyRoomCertificationDTO);
            if (messageVO != null&&0==messageVO.getMsgCode()&&smsSuccess&&StringUtils.isNotBlank(appApplyRoomCertificationDTO.getOwnerPhoneNo())){  //房屋认证业务成功后清除短信验证码缓存
                redisService.del(RedisConstant.REDIS_SMS_CODE+appApplyRoomCertificationDTO.getOwnerPhoneNo());
            }
            return messageVO;
        }catch (Exception e){
            throw  new DataAccessException("【APP_首页版块_房屋认证】用户提交授权认证失败",e);
        }
    }


    /**
     * <desc>
     *     APP端_首页版块，检测更新
     * </desc>
     * @param appType 类型,android/ios/iossdk/androidsdk/androidengineer
     * @param appSort 类别 test/official
     * @return
     * * @createDate 2017/10/10
     * @author cuiduanwu
     */
    @RequestMapping(path = "/versionUpdate",method = RequestMethod.POST)
    @UnAuthAccessRequired
    @ResponseBody
    public Object versionUpdate(String appType,String appSort,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                appType = request.getAttribute("appType") == null ? null : request.getAttribute("appType").toString();
                appSort = request.getAttribute("appSort") == null ? null : request.getAttribute("appSort").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("appType",appType);
            params.put("appSort",appSort);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(appType)||StringUtils.isBlank(appSort)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }else if (StringUtils.isBlank(appType)||StringUtils.isBlank(appSort)||StringUtils.isBlank(createTime)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode():BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            AppPublishInfoPO appPublishInfoPO =null;

            appPublishInfoPO = iAppAppPublishInfoServiceClient.getLatestAppPublishInfo(appType,appSort,language);
            JSONObject js = new JSONObject();
            String appDownloadUrl="",appVersion="",mustUpdate="",remark="";
            if (appPublishInfoPO != null){
                appDownloadUrl = appPublishInfoPO.getAppDownUrl();
                appVersion = appPublishInfoPO.getAppVersion();
                mustUpdate = appPublishInfoPO.getMustUpdate()+"";
                remark = appPublishInfoPO.getRemark();
            }
            js.put("appDownloadUrl",appDownloadUrl);
            js.put("appVersion", StringEscapeUtils.unescapeJava(appVersion));
            js.put("mustUpdate",mustUpdate);
            js.put("msg",remark);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,js);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块_最新版本】获取最新版本失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      获取用户信息
     * </desc>
     *
     * @param projectId 项目id
     * @param token
     * @param deviceType
     * @param createTime 时间戳 参与签名
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/19
     */
    @RequestMapping(value = "/getUserInfo",method = RequestMethod.POST)
    @ResponseBody
    public Object getUserInfo(String projectId,String token,String createTime,String sign,String language,String deviceType, String version){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                deviceType = request.getAttribute("deviceType") == null ? null : request.getAttribute("deviceType").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
                version = request.getAttribute("version") == null ? null : request.getAttribute("version").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                params.put("version",version);
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            //用户是否是vip
            boolean  isVip  = iAppDeviceServiceClient.appUserIsVip(userInfo.getUserId(),projectId);
            userInfo.setIsVip(isVip?1:0);
            //获取用户基础信息
            AppUserInfoPO userPo=(AppUserInfoPO)StringHandlerUtil.formatString(iAppRegisterServiceClient.getBaseUserInfo(userInfo.getUserId())==null?new AppUserInfoPO():iAppRegisterServiceClient.getBaseUserInfo(userInfo.getUserId()));
            userInfo.setNickName(userPo.getNickName());
            userInfo.setUserName(userPo.getRealName());
            userInfo.setPhotoUrl(userPo.getIcon());
            userInfo.setSex(userPo.getGender()!=null?userPo.getGender().toString() : "");
            // 获取用户的第三方账号信息
            String cloudIntercomAccountId = userPo.getCloudIntercomAccountId();
            if (StringUtils.isNotBlank(cloudIntercomAccountId)) {
                CloudIntercomAccountInfoPO clientAccountInfo = iAppRegisterServiceClient.getClientAccount(cloudIntercomAccountId);
                if (clientAccountInfo != null) {
                    CloudIntercomAccountInfoPO cloudIntercomAccountInfoPO = (CloudIntercomAccountInfoPO) StringHandlerUtil.formatString(clientAccountInfo);
                    userInfo.setClientToken(cloudIntercomAccountInfoPO.getToken());
                } else { // 为空的情况去掉缓存中的第三方账号信息
                    userInfo.setClientToken("");
                }
            } else {
                userInfo.setClientToken("");
            }
            List<AppUserOwnProjectVO> userOwnProjectList = null;
            if (!"1".equals(userInfo.getGuestType())) {
                if (StringUtils.isNotBlank(deviceType)) {
                    userOwnProjectList = iAppRegisterServiceClient.getUserOwnProjectsInfo(userInfo.getUserId(), deviceType);
                } else {
                    userOwnProjectList = iAppRegisterServiceClient.getUserOwnProjectsInfo(userInfo.getUserId(), "-1");
                }
                userInfo.setProjects(userOwnProjectList);
                userInfo.setCurrentProjectId("");
                userInfo.setCurrentProjectName("");
            }
            List<String> projectList = new ArrayList<>();
            if(userOwnProjectList != null && userOwnProjectList.size()>0){
                for(AppUserOwnProjectVO projectVO : userOwnProjectList){
                    projectList.add(projectVO.getProjectId());
                }
            }
            //此处处理当单个项目迁出后，后台返回的当前项目还是该项目，多个项目时APP应随机显示其它项目
            String guestProjectId = projectId;
            if((userOwnProjectList != null && !projectList.contains(projectId)) || userOwnProjectList == null){
                projectId = "";
            }
            if (userOwnProjectList != null && !userOwnProjectList.isEmpty()) {
                for (AppUserOwnProjectVO project : userOwnProjectList) {
                    if (project.getProjectId().equals(projectId)) {
                        userInfo.setCurrentProjectId(project.getProjectId());
                        userInfo.setCurrentProjectName(project.getProjectName());
                        userInfo.setCurrentProjectType(project.getProjectType());
                        userInfo.setCurrentOwnerAddress(project.getOwnerAddress());
                        userInfo.setBluetoothThreshold(project.getBluetoothThreshold());
                        // 获取物业管理员手机号，用于联系物业
                        OperateBusinessChargeDTO operateBusinessChargeDTO = new OperateBusinessChargeDTO();
                        operateBusinessChargeDTO.setProjectId(projectId);
                        OperatePropertyInformationGetVO propertyInformation = iOperateBusinessChargeServiceClient.getPropertyInformation(operateBusinessChargeDTO);
                        if (propertyInformation != null && StringUtils.isNotBlank(propertyInformation.getPropertyPhone())) {
                            project.setCenterPhoneNo(propertyInformation.getPropertyPhone());
                        }
                        if ("0".equals(project.getState())) {
                            // 获取项目的设备的云服务费过期时间
                            List<Map<String, Object>> cloudServiceMapList = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(projectId);
                            // 获取项目的云服务费最小过期时间
                            String projectMinEndTime = iAppDeviceServiceClient.getProjectCloudServiceCostMinEndTime(projectId);
//                            if (cloudServiceMapList != null && !cloudServiceMapList.isEmpty()) {
                            //门禁设备信息
                            List<AppDoorDevicesVO> doors = iAppDeviceServiceClient.getDoorDevices(userInfo.getUserId(), projectId, 0);
                            //电梯设备信息
                            List<AppFloorDevicesVO> floors = iAppDeviceServiceClient.getFloorDevices(userInfo.getUserId(), projectId, 0);
                            //云对讲设备信息
                            List<AppCloudIntercomsVO> clouds = iAppDeviceServiceClient.getCloudIntercoms(userInfo.getUserId(), projectId, 0);
                            // 该用户的设备序列号列表
                            List<String> userDeviceUniqueList = new ArrayList<>();
                            if (doors != null && !doors.isEmpty()) {
                                for (AppDoorDevicesVO door : doors) {
                                    userDeviceUniqueList.add(door.getDeviceUnique());
                                }
                            }
                            if (floors != null && !floors.isEmpty()) {
                                for (AppFloorDevicesVO floor : floors) {
                                    userDeviceUniqueList.add(floor.getDeviceUnique());
                                }
                            }
                            if (clouds != null && !clouds.isEmpty()) {
                                for (AppCloudIntercomsVO cloud : clouds) {
                                    userDeviceUniqueList.add(cloud.getDeviceUnique());
                                }
                            }
                            SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YMDSQL);
                            SimpleDateFormat sdf1 = new SimpleDateFormat(DateUtil.DATE_FORMAT_TYPE1);
                            Date nowTime = sdf.parse(sdf.format(new Date()));
                            // 云服务费最大过期时间
                            Long overDay = -10L;
                            // 是否有批次没过期，即有设备可用
                            boolean hasDevice = false;
                            // 收取云服务费的设备列表
                            List<String> cloudCostDeviceUniqueList = new ArrayList<>();
                            for (Map map : cloudServiceMapList) {
                                cloudCostDeviceUniqueList.add(map.get("deviceUnique").toString());
                                if (!userDeviceUniqueList.contains(map.get("deviceUnique").toString())) {
                                    continue;
                                }
                                Date deviceEndDate = sdf.parse(map.get("endTime").toString());
                                long endDay = (nowTime.getTime() - deviceEndDate.getTime()) / (24 * 60 * 60 * 1000);
                                if (endDay > overDay) {
                                    overDay = endDay;
                                }
                                if (endDay <= 3) {
                                    hasDevice = true;
                                }
                            }
                                /*// 判断用户设备是否存在不收云服务费
                                if (!hasDevice) {
                                    for (String deviceUnique : userDeviceUniqueList) {
                                        if (!cloudCostDeviceUniqueList.contains(deviceUnique)) {
                                            hasDevice = true;
                                            break;
                                        }
                                    }
                                }*/
                            // 最新逻辑，无批次号设备以项目云服务费最小过期时间为准
                            if (StringUtils.isNotBlank(projectMinEndTime)) {
                                for (String deviceUnique : userDeviceUniqueList) {
                                    if (!cloudCostDeviceUniqueList.contains(deviceUnique)) {
                                        Date projectMinEndDate = sdf.parse(projectMinEndTime);
                                        long endDay = (nowTime.getTime() - projectMinEndDate.getTime()) / (24 * 60 * 60 * 1000);
                                        if (endDay > overDay) {
                                            overDay = endDay;
                                        }
                                        if (endDay <= 3) {
                                            hasDevice = true;
                                        }
                                        break;
                                    }
                                }
                            }
                            if (overDay == -7 || overDay == -3 || overDay == -2 || overDay == -1) {
                                // 添加推送消息
                                long day = 0 - overDay;
                                OperateSavePushInfoDTO operateSavePushInfoDTO = new OperateSavePushInfoDTO();
                                operateSavePushInfoDTO.setInfoType(0);
                                operateSavePushInfoDTO.setInfoContent("尊敬的户主您好，您所使用的手机通行设备云空间服务费将在" + day + "天后到期，部分功能即将禁用，请及时联系物业了解详情。");
                                operateSavePushInfoDTO.setBeginDate(sdf1.format(new Date()));
                                operateSavePushInfoDTO.setEndDate("2099-12-31 23:59:59");
                                operateSavePushInfoDTO.setTitle("云空间服务费到期提醒");
                                operateSavePushInfoDTO.setProjectIds(projectId);
                                iOperatePushInfoServiceClient.savePushInfo(operateSavePushInfoDTO);
                            } else if (overDay > 0 && overDay <= 3) {
                                project.setState("3");
                                project.setProjectMessage(overDay.toString());
                            } else if (overDay > 3 && !hasDevice) {
                                project.setState("4");
                                project.setProjectMessage("已过期");
                            } else if (overDay > 3 && hasDevice) {
                                project.setState("5");
                                project.setProjectMessage("已过期");
                            }
//                            }
                        }
                        break;
                    }
                }
            }
            // 已登录app用户的游客项目
            //2021-2-3日更改逻辑，不管是正常登录还是游客登录，当currentProjectId为空时都展示游客项目
            if (StringUtils.isBlank(userInfo.getCurrentProjectId())) {
                AppUserOwnProjectVO appUserOwnProjectVO = iAppRegisterServiceClient.getGuestProject(guestProjectId);
                List<AppUserOwnProjectVO> projects = userInfo.getProjects();
                if (appUserOwnProjectVO != null && StringUtils.isNotBlank(appUserOwnProjectVO.getProjectId())) {
                    userInfo.setCurrentProjectId(appUserOwnProjectVO.getProjectId());
                    userInfo.setCurrentProjectName(appUserOwnProjectVO.getProjectName());
                    userInfo.setCurrentProjectType(appUserOwnProjectVO.getProjectType());
                    userInfo.setCurrentOwnerAddress("0");
                    userInfo.setBluetoothThreshold(appUserOwnProjectVO.getBluetoothThreshold());
                    if (projects == null) {
                        projects = new ArrayList<>();
                        projects.add(appUserOwnProjectVO);
                    } else {
                        projects.add(appUserOwnProjectVO);
                    }
                    userInfo.setProjects(projects);
                } else {
                    if (projects != null && !projects.isEmpty()) {
                        userInfo.setCurrentProjectId(projects.get(0).getProjectId());
                        userInfo.setCurrentProjectName(projects.get(0).getProjectName());
                        userInfo.setBluetoothThreshold(projects.get(0).getBluetoothThreshold());
                        userInfo.setCurrentProjectType(projects.get(0).getProjectType());
                        userInfo.setCurrentOwnerAddress(projects.get(0).getOwnerAddress());
                    }
                }
            }

            //根据userId和projectId查询该用户是否欠费
            if(iAppRegisterServiceClient.getUserIsForbidden(projectId,userInfo.getUserId())>0){
                userInfo.setForbidden("1");
            }else{
                userInfo.setForbidden("0");
            }
            // 获取用户项目信息状态（目前只有缴费通知）、欠费房间id
            AppUserCacheVO appUserCacheSimple = iAppRegisterServiceClient.getUserMsgAndRoomId(userInfo.getCurrentProjectId(), userInfo.getUserId(), version);
            userInfo.setHasNewMsg(appUserCacheSimple.getHasNewMsg());
            userInfo.setRoomId(appUserCacheSimple.getRoomId());

            userInfo.setTime(System.currentTimeMillis()+"");
            //设置当前用户所在项目
            iAppProjectServiceClient.setCurrentProject(userInfo.getUserId(),userInfo.getCurrentProjectId(),userInfo.getCurrentProjectName());
            //设置用户缓存
            redisService.set(RedisConstant.APP_LOGIN+userInfo.getUserId(),RedisConstant.APP_USER_TOKEN_TIME,userInfo);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,userInfo);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】获取用户信息失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      更新个人设备排序值
     * </desc>
     *
     * @param deviceUniques 设备排序逗号分隔
     * @param token
     * @param createTime 时间戳参与签名
     * @return
     * @author Qiang.S
     * @createDate 2019/08/07
     */
    @LoggerInfo(operateDesc = LogDescConstant.UPLOAD_DEVICE_ORDER)
    @RequestMapping(value = "/uploadDeviceOrder",method = RequestMethod.POST)
    @ResponseBody
    public Object uploadDeviceOrder(String deviceUniques,String projectId,String token,String createTime,String sign,String language, String deviceType){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceUniques = request.getAttribute("deviceUniques") == null ? null : request.getAttribute("deviceUniques").toString();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
                deviceType = request.getAttribute("deviceType") == null ? "" : request.getAttribute("deviceType").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("deviceUniques",deviceUniques);
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                params.put("deviceType",deviceType);
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(token);
            iAppDeviceServiceClient.uploadDeviceOrder(userInfo.getUserId(),projectId,deviceUniques, deviceType);
            messageVO =  new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】保存设备排序失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      保存设备排序信息
     * </desc>
     *
     * @param groupConId 群控器或电梯编号逗号分隔
     * @param createTime 时间戳参与签名
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/05/06
     */
    @LoggerInfo(operateDesc = LogDescConstant.UPLOAD_DEVICE_ORDER)
    @RequestMapping(value = "/uploadNewDeviceOrder", method = RequestMethod.POST)
    @ResponseBody
    public Object uploadNewDeviceOrder(String groupConId, String projectId, String token, String createTime, String sign, String language) {
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            groupConId = request.getAttribute("groupConId") == null ? null : request.getAttribute("groupConId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("groupConId", groupConId);
            params.put("projectId", projectId);
            params.put("createTime", createTime);
            params.put("language", language);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            if (StringUtils.isBlank(groupConId) || StringUtils.isBlank(projectId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo = userCache.retrieve(token);
            iAppDeviceServiceClient.uploadDeviceOrder(userInfo.getUserId(), projectId, groupConId, "3");
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】保存设备排序失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取项目列表，包含游客身份即定位获取的项目
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/04/30
     */
    @RequestMapping(value = "/getAllLocationProjects", method = RequestMethod.POST)
    @ResponseBody
    public Object getAllLocationProjects(String token, String longitude, String latitude, String createTime, String sign, String language) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            longitude = request.getAttribute("longitude") == null ? null : request.getAttribute("longitude").toString();
            latitude = request.getAttribute("latitude") == null ? null : request.getAttribute("latitude").toString();
            token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("longitude", longitude);
            params.put("latitude", latitude);
            params.put("createTime", createTime);
            params.put("language", language);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            ///解密拿到userId
            String userId = UserTokenUtil.newAPPTokenDecrypt(token, APP_USER_TOKEN_KEY);
            List<AppUserOwnProjectVO> userOwnProjectsInfo = iAppRegisterServiceClient.getUserOwnProjectsInfo(userId, "-1");
            List<Map<String, Object>> resultList = new ArrayList<>();
            if (userOwnProjectsInfo != null && !userOwnProjectsInfo.isEmpty()) {
                for (AppUserOwnProjectVO appUserOwnProjectVO : userOwnProjectsInfo) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("projectName", appUserOwnProjectVO.getProjectName());
                    map.put("projectId", appUserOwnProjectVO.getProjectId());
                    map.put("state", appUserOwnProjectVO.getState());
                    map.put("projectType", appUserOwnProjectVO.getProjectType() == null ? "" : appUserOwnProjectVO.getProjectType());
                    map.put("ownerAddress", appUserOwnProjectVO.getOwnerAddress());
                    map.put("deleteFlag", appUserOwnProjectVO.getDeleteFlag());
                    resultList.add(map);
                }
            }
            if (StringUtils.isNotBlank(longitude) && StringUtils.isNotBlank(latitude)) {
                AppTouristDTO appTouristDTO = new AppTouristDTO();
                appTouristDTO.setPosition(longitude + "," + latitude);
                Map<String, Object> data = iAppProjectServiceClient.getProjectByLocation(appTouristDTO);
                if (data.get("projectId") != null && StringUtils.isNotBlank(data.get("projectId").toString())) {
                    boolean guestFlag = true;
                    if (userOwnProjectsInfo != null && !userOwnProjectsInfo.isEmpty()) {
                        for (AppUserOwnProjectVO appUserOwnProjectVO : userOwnProjectsInfo) {
                            if (appUserOwnProjectVO.getProjectId().equals(data.get("projectId").toString())) {
                                guestFlag = false;
                                break;
                            }
                        }
                    }
                    if (guestFlag) {
                        Map<String, Object> map = new HashMap<>();
                        map.put("projectName", data.get("projectName"));
                        map.put("projectId", data.get("projectId"));
                        map.put("state", "0");
                        resultList.add(map);
                        // 保存或修改游客项目历史数据
                        GuestUserHistoryPO guestUserHistoryPO = new GuestUserHistoryPO();
                        guestUserHistoryPO.setUserId(userId);
                        guestUserHistoryPO.setProjectId(data.get("projectId").toString());
                        guestUserHistoryPO.setSource(1);
                        iAppRegisterServiceClient.saveOrUpdateGuestProject(guestUserHistoryPO);
                    }
                }
            }
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.SUCCESS.getErrorCode() : BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            return new MessageVO(errorCode, resultList);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】获取项目列表失败",e);
        }
    }

    /**
     * <desc>
     *      获取设备列表
     * </desc>
     *
     * @param token
     * @param createTime 时间戳参与签名
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/19
     */
    @RequestMapping(value = "/getDeviceList",method = RequestMethod.POST)
    @ResponseBody
    public Object getDeviceList(String token,String createTime,String sign,String language){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(token);
            if (userInfo==null || userInfo.getUserId() == null) {
                return new MessageVO(AppErrorCodeEnum.MANAGEMENT_USER_TOKEN_ERROR.getErrorCode());
            }
            //获取项目id
            String projectIds=iAppProjectServiceClient.getUserProjectIds(userInfo.getUserId());
            projectIds=StringUtils.isNotBlank(projectIds) ? projectIds : "";
            List<AppGetUserDevicesListVO> list=new ArrayList<>();
            String[] arrayProject=StringHandlerUtil.splitString(projectIds);
            //获取用户所有项目的设备信息
            if(arrayProject.length>0){
                for(String projectId:arrayProject) {
                    //门禁设备信息
                    List<AppDoorDevicesVO> doors = iAppDeviceServiceClient.getDoorDevices(userInfo.getUserId(), projectId, 0);
                    //电梯设备信息
                    List<AppFloorDevicesVO> floors=iAppDeviceServiceClient.getFloorDevices(userInfo.getUserId(),projectId,1);
                    //云对讲设备信息
                    List<AppCloudIntercomsVO> clouds=iAppDeviceServiceClient.getCloudIntercoms(userInfo.getUserId(),projectId,0);
                    AppGetUserDevicesListVO vo=new AppGetUserDevicesListVO();
                    List<AppCloudAndEntranceDeviceVO> ces=new ArrayList<>();
                    //查询项目下云对讲是否有权限
                    String cloudStatus=iAppDeviceServiceClient.getProjectIsSmartCommunity(projectId);
                    if(StringUtils.isNotBlank(cloudStatus)){
                        vo.setCloudStatus(cloudStatus);
                    }else{
                        vo.setCloudStatus("0");
                    }
                    vo.setProjectId(projectId);
                    Set<String> outCalls = new HashSet<>();
                    if(floors!=null && !floors.isEmpty()) {
                        //电梯去null
                        floors.forEach(floor->{
                            floor=(AppFloorDevicesVO)StringHandlerUtil.formatString(floor);
                            if(StringUtils.isNotBlank(floor.getBlueToothDevices())){
                                outCalls.add(floor.getBlueToothDevices());
                            }
                        });
                    }
                    if(doors!=null) {
                        for (AppDoorDevicesVO door : doors) {
                            AppCloudAndEntranceDeviceVO doorVO = new AppCloudAndEntranceDeviceVO();
                            doorVO.setEntranceDeviceVO(door.getDeviceName(), door.getDeviceUnique(), door.getProjectId(),
                                    door.getProtocolVersion(), door.getThreshold(), door.getDoorAuth(),
                                    door.getCardNum(), door.getValiTime(), door.getPosition());
                            doorVO.setSystemType(1);
                            doorVO.setDoorType(door.getDoorType());
                            ces.add((AppCloudAndEntranceDeviceVO) StringHandlerUtil.formatString(doorVO));
                        }
                    }
                    if(clouds!=null) {
                        for (AppCloudIntercomsVO cloud : clouds) {
                            AppCloudAndEntranceDeviceVO cloudVO = new AppCloudAndEntranceDeviceVO();
                            cloudVO.setCloudVO(cloud.getDeviceName(), cloud.getDeviceUnique(), cloud.getProjectId(),
                                    cloud.getCardNum(), cloud.getRoomIds(), cloud.getValiTime(), cloud.getSipAccount(),
                                    cloud.getRoomNum(), cloud.getPosition(),cloud.getClientAccount());
                            cloudVO.setSystemType(cloud.getSystemType());
                            ces.add((AppCloudAndEntranceDeviceVO) StringHandlerUtil.formatString(cloudVO));
                        }
                    }
                    vo=(AppGetUserDevicesListVO)StringHandlerUtil.formatString(vo);
                    // 云服务费过期时间判断
                    List<Map<String, Object>> cloudServiceMapList = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(projectId);
                    // 获取项目的云服务费最小过期时间
                    String projectMinEndTime = iAppDeviceServiceClient.getProjectCloudServiceCostMinEndTime(projectId);
//                    if (cloudServiceMapList != null && !cloudServiceMapList.isEmpty()) {
                    SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YMDSQL);
                    Date nowTime = sdf.parse(sdf.format(new Date()));
                    // 已配置云服务费的设备序列号列表
                    List<String> cloudCostDeviceUniqueList = new ArrayList<>();
                    // 过期超3天不可用设备序列号列表
                    List<String> overDevice = new ArrayList<>();
                    for (Map map : cloudServiceMapList) {
                        cloudCostDeviceUniqueList.add(map.get("deviceUnique").toString());
                        Date deviceEndDate = sdf.parse(map.get("endTime").toString());
                        long endDay = (nowTime.getTime() - deviceEndDate.getTime()) / (24 * 60 * 60 * 1000);
                        if (endDay > 3) {
                            overDevice.add(map.get("deviceUnique").toString());
                        }
                    }
                    // 最新逻辑，无批次号设备以项目云服务费最小过期时间为准
                    Long overDay = -10L;
                    if (StringUtils.isNotBlank(projectMinEndTime)) {
                        Date projectMinEndDate = sdf.parse(projectMinEndTime);
                        overDay = (nowTime.getTime() - projectMinEndDate.getTime()) / (24 * 60 * 60 * 1000);
                    }
                    // 按最新业务逻辑改动，未配置云服务费的也禁止使用
                    List<AppFloorDevicesVO> floorsForLoop = new ArrayList<>(floors);
                    for (AppFloorDevicesVO floor : floorsForLoop) {
                        if (overDevice.contains(floor.getDeviceUnique()) ||
                                (!cloudCostDeviceUniqueList.contains(floor.getDeviceUnique()) && overDay > 3)) {
                            floors.remove(floor);
                        }
                    }
                    List<AppCloudAndEntranceDeviceVO> cesForLoop = new ArrayList<>(ces);
                    for (AppCloudAndEntranceDeviceVO door : cesForLoop) {
                        if (overDevice.contains(door.getDeviceUnique()) ||
                                (!cloudCostDeviceUniqueList.contains(door.getDeviceUnique()) && overDay > 3)) {
                            ces.remove(door);
                        }
                    }
//                    }
                    //根据userId和projectId查询该用户是否欠费
                    if (iAppRegisterServiceClient.getUserIsForbidden(projectId, userInfo.getUserId()) > 0) {
                        floors = new ArrayList<>();
                        ces = new ArrayList<>();
                    }
                    vo.setFloorDevices(floors);
                    vo.setDoorDevices(ces);
                    //使用用户自定义顺序排序
                    String deviceUniques = iAppDeviceServiceClient.getUserDeviceOrder(userInfo.getUserId(),projectId);
                    if (!StringUtils.isBlank(deviceUniques)) {
                        String[] deviceUnique = deviceUniques.split(",");
                        List<AppCloudAndEntranceDeviceVO> cesNew=new ArrayList<>();
                        for (String order : deviceUnique) {
                            for (AppCloudAndEntranceDeviceVO info : ces) {
                                if (info.getDeviceUnique().equals(order)) {
                                    cesNew.add(info);
                                }
                            }
                        }
                        ces.removeAll(cesNew);
                        cesNew.addAll(ces);
                        vo.setDoorDevices(cesNew);
                    } else {
                        vo.setDoorDevices(ces);
                    }
                    String elevatorOrder = iAppDeviceServiceClient.getUserElevatorOrder(userInfo.getUserId(), projectId);
                    if (StringUtils.isNotBlank(elevatorOrder) && floors != null && !floors.isEmpty()) {
                        String[] elevatorOrderArr = elevatorOrder.split(",");
                        List<AppFloorDevicesVO> elevatorNew = new ArrayList<>();
                        for (String order : elevatorOrderArr) {
                            for (AppFloorDevicesVO info : floors) {
                                if (info.getDeviceUnique().equals(order)) {
                                    elevatorNew.add(info);
                                }
                            }
                        }
                        floors.removeAll(elevatorNew);
                        elevatorNew.addAll(floors);
                        vo.setFloorDevices(elevatorNew);
                    }
                    String userCommonFloor = iAppDeviceServiceClient.getUserCommonFloor(userInfo.getUserId(), projectId);
                    if (StringUtils.isNotBlank(userCommonFloor) && vo.getFloorDevices() != null && !vo.getFloorDevices().isEmpty()) {
                        Map<String, Object> userCommonFloorMap = JSON.parseObject(userCommonFloor, HashMap.class);
                        if (userCommonFloorMap != null && !userCommonFloorMap.isEmpty()) {
                            for (AppFloorDevicesVO info : vo.getFloorDevices()) {
                                info.setLiveChoiceFloor(
                                        userCommonFloorMap.get(info.getDeviceUnique()) == null ? info.getLiveChoiceFloor() : userCommonFloorMap.get(info.getDeviceUnique()).toString());
                            }
                        }
                    }
                    list.add(vo);
                }
            }
            Map<String,Object> data=new HashMap<>();
            data.put("allDeviceList",list);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,data);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】获取设备列表失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取设备列表
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/05/07
     */
    @RequestMapping(value = "/getAllDevice", method = RequestMethod.POST)
    @ResponseBody
    public Object getAllDevice(String projectId, String token, String createTime, String sign, String language) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("createTime", createTime);
            params.put("language", language);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            if (StringUtils.isBlank(projectId)) {
                AppGetDeviceListVO appGetDeviceListVO = new AppGetDeviceListVO();
                appGetDeviceListVO.setOutCallAry(new ArrayList<>());
                appGetDeviceListVO.setDoorAry(new ArrayList<>());
                appGetDeviceListVO.setLiftAry(new ArrayList<>());
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.SUCCESS.getErrorCode() : BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
                return new MessageVO(errorCode, appGetDeviceListVO);
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = userCache.retrieve(token);
            //门禁设备信息
            List<AppDoorDevicesVO> doors = iAppDeviceServiceClient.getDoorDevices(userInfo.getUserId(), projectId, 0);
            //电梯设备信息
            List<AppFloorDevicesVO> floors = iAppDeviceServiceClient.getFloorDevices(userInfo.getUserId(), projectId, 0);
            //云对讲设备信息
            List<AppCloudIntercomsVO> clouds = iAppDeviceServiceClient.getCloudIntercoms(userInfo.getUserId(), projectId, 0);
            // 获取游客模式下有公共楼层的电梯设备
            List<AppFloorDevicesVO> floorGuestList = iAppDeviceServiceClient.getGuestFloorList(projectId);
            List<String> floorDeviceUniqueList = new ArrayList<>();
            List<AppCloudTalkAndEntranceDeviceVO> ces = new ArrayList<>();
            for (AppFloorDevicesVO appFloorDevicesVO : floors) {
                floorDeviceUniqueList.add(appFloorDevicesVO.getDeviceUnique());
                //逆序排列常用楼层和公共楼层
                appFloorDevicesVO.setCommonFloor(StringHandlerUtil.getReverseStr(appFloorDevicesVO.getCommonFloor()));
                appFloorDevicesVO.setCommonLogicalFloor(StringHandlerUtil.getReverseStr(appFloorDevicesVO.getCommonLogicalFloor()));
                appFloorDevicesVO.setLiveFloor(StringHandlerUtil.getReverseStr(appFloorDevicesVO.getLiveFloor()));
                appFloorDevicesVO.setLiveLogicalFloor(StringHandlerUtil.getReverseStr(appFloorDevicesVO.getLiveLogicalFloor()));
            }
            for (AppFloorDevicesVO appFloorDevicesVO : floorGuestList) {
                if (!floorDeviceUniqueList.contains(appFloorDevicesVO.getDeviceUnique())) {
                    floors.add(appFloorDevicesVO);
                    floorDeviceUniqueList.add(appFloorDevicesVO.getDeviceUnique());
                }
            }
            Set<String> outCalls = new HashSet<>();
            if (!floors.isEmpty()) {
                // 电梯去null
                floors.forEach(floor->{
                    floor=(AppFloorDevicesVO)StringHandlerUtil.formatString(floor);
                    if(StringUtils.isNotBlank(floor.getBlueToothDevices())){
                        outCalls.add(floor.getBlueToothDevices());
                    }
                });
            }
            List<AppOutCallDevicesVO> outCallDevices = null;
            if(!outCalls.isEmpty()){
                //查询蓝牙外呼设备
                outCallDevices = iAppDeviceServiceClient.getOutCallDevices(StringUtils.join(outCalls,","),floors.get(0).getThreshold());
            }else{
                outCallDevices = new ArrayList<>();
            }
            if (doors != null) {
                for (AppDoorDevicesVO door : doors) {
                    AppCloudTalkAndEntranceDeviceVO appCloudTalkAndEntranceDeviceVO = new AppCloudTalkAndEntranceDeviceVO();
                    appCloudTalkAndEntranceDeviceVO.setEntranceDeviceVO(door.getDeviceName(), door.getDeviceUnique(), door.getProjectId(),
                            door.getProtocolVersion(), door.getThreshold(), door.getDoorAuth(),
                            door.getCardNum(), door.getValiTime(), door.getPosition());
                    appCloudTalkAndEntranceDeviceVO.setSystemType(1);
                    appCloudTalkAndEntranceDeviceVO.setDoorType(door.getDoorType());
                    ces.add((AppCloudTalkAndEntranceDeviceVO) StringHandlerUtil.formatString(appCloudTalkAndEntranceDeviceVO));
                }
            }
            if (clouds != null) {
                for (AppCloudIntercomsVO cloud : clouds) {
                    AppCloudTalkAndEntranceDeviceVO appCloudTalkAndEntranceDeviceVO = new AppCloudTalkAndEntranceDeviceVO();
                    appCloudTalkAndEntranceDeviceVO.setCloudVO(cloud.getDeviceName(), cloud.getDeviceUnique(), cloud.getProjectId(),
                            cloud.getCardNum(), cloud.getRoomIds(), cloud.getValiTime(), cloud.getSipAccount(),
                            cloud.getRoomNum(), cloud.getPosition(), cloud.getClientAccount());
                    appCloudTalkAndEntranceDeviceVO.setSystemType(cloud.getSystemType());
                    ces.add((AppCloudTalkAndEntranceDeviceVO) StringHandlerUtil.formatString(appCloudTalkAndEntranceDeviceVO));
                }
            }
            // 云服务费过期时间判断
            List<Map<String, Object>> cloudServiceMapList = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(projectId);
            // 获取项目的云服务费最小过期时间
            String projectMinEndTime = iAppDeviceServiceClient.getProjectCloudServiceCostMinEndTime(projectId);
            SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.YMDSQL);
            Date nowTime = sdf.parse(sdf.format(new Date()));
            // 已配置云服务费的设备序列号列表
            List<String> cloudCostDeviceUniqueList = new ArrayList<>();
            // 过期超3天不可用设备序列号列表
            List<String> overDevice = new ArrayList<>();
            for (Map map : cloudServiceMapList) {
                cloudCostDeviceUniqueList.add(map.get("deviceUnique").toString());
                Date deviceEndDate = sdf.parse(map.get("endTime").toString());
                long endDay = (nowTime.getTime() - deviceEndDate.getTime()) / (24 * 60 * 60 * 1000);
                if (endDay > 3) {
                    overDevice.add(map.get("deviceUnique").toString());
                }
            }
            // 最新逻辑，无批次号设备以项目云服务费最小过期时间为准
            Long overDay = -10L;
            if (StringUtils.isNotBlank(projectMinEndTime)) {
                Date projectMinEndDate = sdf.parse(projectMinEndTime);
                overDay = (nowTime.getTime() - projectMinEndDate.getTime()) / (24 * 60 * 60 * 1000);
            }
            // 按最新业务逻辑改动，未配置云服务费的也禁止使用
            List<AppFloorDevicesVO> floorsForLoop = new ArrayList<>(floors);
            for (AppFloorDevicesVO floor : floorsForLoop) {
                if (overDevice.contains(floor.getDeviceUnique()) ||
                        (!cloudCostDeviceUniqueList.contains(floor.getDeviceUnique()) && overDay > 3)) {
                    floors.remove(floor);
                }
            }
            List<AppCloudTalkAndEntranceDeviceVO> cesForLoop = new ArrayList<>(ces);
            for (AppCloudTalkAndEntranceDeviceVO door : cesForLoop) {
                if (overDevice.contains(door.getDeviceUnique()) ||
                        (!cloudCostDeviceUniqueList.contains(door.getDeviceUnique()) && overDay > 3)) {
                    ces.remove(door);
                }
            }
            //根据userId和projectId查询该用户是否欠费
            if (iAppRegisterServiceClient.getUserIsForbidden(projectId, userInfo.getUserId()) > 0) {
                floors = new ArrayList<>();
                ces = new ArrayList<>();
            }
            //使用用户自定义顺序排序 云对讲、门禁
            String deviceUniques = iAppDeviceServiceClient.getUserDeviceOrder(userInfo.getUserId(), projectId);
            if (StringUtils.isNotBlank(deviceUniques) && ces != null && !ces.isEmpty()) {
                String[] deviceUnique = deviceUniques.split(",");
                List<AppCloudTalkAndEntranceDeviceVO> cesNew = new ArrayList<>();
                for (String order : deviceUnique) {
                    for (AppCloudTalkAndEntranceDeviceVO info : ces) {
                        if (info.getDeviceUnique().equals(order)) {
                            cesNew.add(info);
                            break;
                        }
                    }
                }
                ces.removeAll(cesNew);
                cesNew.addAll(ces);
                ces = cesNew;
            }
            //常用楼层
            String userCommonFloor = iAppDeviceServiceClient.getUserCommonFloor(userInfo.getUserId(), projectId);
            Map<String, Object> userCommonFloorMap = null;
            if (StringUtils.isNotBlank(userCommonFloor)) {
                userCommonFloorMap = JSON.parseObject(userCommonFloor, HashMap.class);
            }
            //常用公共楼层
            String userPublicFloor = iAppDeviceServiceClient.getUserPublicFloor(userInfo.getUserId(), projectId);
            Map<String, Object> userPublicFloorMap = null;
            if (StringUtils.isNotBlank(userPublicFloor)) {
                userPublicFloorMap = JSON.parseObject(userPublicFloor, HashMap.class);
            }
            //筛选常用楼层和常用公共楼层
            if ( floors != null && !floors.isEmpty()) {
                for (AppFloorDevicesVO info : floors) {
                    if (  userCommonFloorMap != null && !userCommonFloorMap.isEmpty()) {
                        info.setLiveChoiceFloor(
                                userCommonFloorMap.get(info.getDeviceUnique()) == null ? info.getLiveChoiceFloor() : userCommonFloorMap.get(info.getDeviceUnique()).toString());
                    }
                    if (  userPublicFloorMap != null && !userPublicFloorMap.isEmpty()) {
                        info.setCommonChoiceFloor(
                                userPublicFloorMap.get(info.getDeviceUnique()) == null ? info.getCommonChoiceFloor() : userPublicFloorMap.get(info.getDeviceUnique()).toString());
                    }

                }
            }

            //使用用户自定义顺序排序 电梯、群控器，先排序，再做以群控器为基准的合并操作
            String elevatorControllerOrder = iAppDeviceServiceClient.getUserElevatorControllerOrder(userInfo.getUserId(), projectId);
            if (StringUtils.isNotBlank(elevatorControllerOrder) && floors != null && !floors.isEmpty()) {
                String[] elevatorControllerOrderArr = elevatorControllerOrder.split(",");
                List<AppFloorDevicesVO> elevatorNew = new ArrayList<>();
                for (String order : elevatorControllerOrderArr) {
                    for (AppFloorDevicesVO info : floors) {
                        // 注意在一种情况下，即本来电梯和群控器的组合已经排过序了，但是后来某个电梯添加到了某个群控器中去，此时elevatorNew要过滤，否则会出现两个相同的元素
                        if ((info.getDeviceUnique().equals(order) || info.getGroupConId().equals(order)) && !elevatorNew.contains(info)) {
                            elevatorNew.add(info);
                        }
                    }
                }
                floors.removeAll(elevatorNew);
                elevatorNew.addAll(floors);
                floors = elevatorNew;
            }
            // 做合并操作
            List<List<AppFloorDeviceVO>> liftAry = new ArrayList<>();
            // floorIndex作为设备对于liftAry的索引记录
            Map<String, Integer> floorIndex = new HashMap<>();
            for (AppFloorDevicesVO floor : floors) {
                //权限去冗余，物业后台可能会将这个选中的楼层（常用或者公共）移除权限
                String  allFloorStr  =   floor.getFloors();
                List<String>  allFloorList =  new ArrayList<String>();
                if(StringUtils.isNotEmpty(allFloorStr)){
                    allFloorList  =  Arrays.asList(allFloorStr.split(","));
                }
                String  cCFloor   =  floor.getCommonChoiceFloor();
                String  lCFloor     =  floor.getLiveChoiceFloor();
                if(  (!allFloorList.contains(cCFloor))  &&  (!"x".equals(cCFloor))){
                    floor.setCommonChoiceFloor("");
                }
                if(  (!allFloorList.contains(lCFloor))  &&  (!"x".equals(lCFloor))){
                    floor.setLiveChoiceFloor("");
                }

                AppFloorDeviceVO appFloorDeviceVO = new AppFloorDeviceVO();
                BeanUtils.copyProperties(floor, appFloorDeviceVO);
                Integer index;
                if (StringUtils.isBlank(appFloorDeviceVO.getGroupConId())) {
                    index = floorIndex.get(appFloorDeviceVO.getDeviceUnique());
                } else {
                    index = floorIndex.get(appFloorDeviceVO.getGroupConId());
                }
                if (index == null) {
                    // 此设备在列表中还没有分组
                    List<AppFloorDeviceVO> appFloorDeviceVOS = new ArrayList<>();
                    appFloorDeviceVOS.add(appFloorDeviceVO);
                    liftAry.add(appFloorDeviceVOS);
                    floorIndex.put(StringUtils.isBlank(appFloorDeviceVO.getGroupConId()) ? appFloorDeviceVO.getDeviceUnique() : appFloorDeviceVO.getGroupConId(), liftAry.size() - 1);
                } else {
                    // 此设备在列表中已有分组
                    liftAry.get(index).add(appFloorDeviceVO);
                }
            }
            AppGetDeviceListVO appGetDeviceListVO = new AppGetDeviceListVO();
            appGetDeviceListVO.setOutCallAry(outCallDevices);
            appGetDeviceListVO.setDoorAry(ces);
            appGetDeviceListVO.setLiftAry(liftAry);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.SUCCESS.getErrorCode() : BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            return new MessageVO(errorCode, appGetDeviceListVO);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】获取设备列表失败", e);
        }
    }

    /**
     * <desc>
     *      远程开门
     * </desc>
     *
     * @param projectId 项目id
     * @param auth 设备信息
     * @param createTime 时间戳 参与签名
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/25
     */
    @ResponseBody
    @RequestMapping("/remoteOpenDoor")
    @LoggerInfo(operateDesc = LogDescConstant.REMOTE_OPEN_DOOR)
    public Object remoteOpenDoor(String projectId,String auth,String createTime,String sign,String language) throws Exception{
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                auth = request.getAttribute("auth") == null ? null : request.getAttribute("auth").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("auth",auth);
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(projectId) || !projectId.matches("[0-9]{8}")){
                LOG.info("【APP_首页版块】远程开门_项目编号非法】"+projectId);
                return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
            }else if (StringUtils.isBlank(auth)){
                return new MessageVO(AppErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            JSONObject msg = new JSONObject();
            msg.put("auth", auth);
            AppErrorCodeEnum code = iMinaServiceClient.sendMessage(projectId, msg.toJSONString());
            Map<String,Object> result=new HashMap<>();
            if(code.getErrorCode().getSubCode()==AppErrorCodeEnum.OPEN_SUCCESS.getErrorCode().getSubCode()){
                result.put("resultCode",1);
                messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
            }else {
                result.put("resultCode",0);
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
            }
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】远程开门失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取通行密码
     * </desc>
     *
     * @param dto 接收数据dto类
     * @param sign 签名
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/30
     */
    @LoggerInfo(operateDesc = LogDescConstant.APP_GETVISITPASSWORD_ERROR)
    @RequestMapping(path = "/getVisitPassWord",method = RequestMethod.POST)
    @ResponseBody
    public Object getVisitPassWord(AppGetVisitPassWordDTO dto,String sign){
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String encryptScript = request.getParameter("ciphertext");
            boolean flag = StringUtils.isNotBlank(sign);
            if (!flag) {
                dto = HttpProtocolUtil.parseRequestParamToDTO(AppGetVisitPassWordDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            Map<String,String> params = new HashMap<>();
            params.put("visitorName",dto.getVisitorName());
            params.put("visitorPhoneNumber",dto.getVisitorPhoneNumber());
            params.put("countLimit",dto.getCountLimit());
            params.put("timeLimit",dto.getTimeLimit());
            params.put("roomId",dto.getRoomId());
            params.put("projectId",dto.getProjectId());
            params.put("createTime",dto.getCreateTime());
            params.put("language",dto.getLanguage());
            //此处判断为兼容新旧版本问题
            if (!StringUtils.isBlank(encryptScript)) {
                params.put("deviceUniques",dto.getDeviceUniques());
            }
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(dto.getProjectId()) || !dto.getProjectId().matches("[0-9]{8}")){
                LOG.info("【APP_首页版块】获取通行密码_项目编号非法】"+dto.getProjectId());
                return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
            }else if(StringUtils.isBlank(dto.getVisitorName())){
                return new MessageVO(AppErrorCodeEnum.VISIT_NAME_IS_NULL.getErrorCode());
            }else if(dto.getVisitorName().length() > 10){
                return new MessageVO(AppErrorCodeEnum.VISIT_NAME_IS_ERROR.getErrorCode());
            }else if(StringUtils.isBlank(dto.getVisitorPhoneNumber())){
                return new MessageVO(AppErrorCodeEnum.VISIT_PHONE_IS_NULL.getErrorCode());
            }else if(!dto.getVisitorPhoneNumber().matches("[0-9]{11}")){
                return new MessageVO(AppErrorCodeEnum.VISIT_PHONE_IS_ERROR.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(dto.getToken());
            dto.setLoginUserId(userInfo.getUserId());
            dto.setLoginUserPhone(userInfo.getPhoneNo());
            //设置动态密码
            //LOG.info("【APP生成访客请求入参dto】:"+dto.toString());
            AppVisitorPassCodeRecordPO po=iAppVisitorPassCodeRecordServiceClient.save(dto);
            if(po.getResult().equals("SUCCESS")) {
                AppGetVisitPassWordVO vo = new AppGetVisitPassWordVO();
                vo.setPassId(po.getPassId());
                vo.setPassWord(po.getPassword());
                vo.setQrcode(po.getQrcode());
                vo.setCountLimit(po.getNum().toString());
                vo.setStartTime(DateUtil.fomatDate(po.getStartTime(), DateUtil.YYYYMMDDHHMM));
                vo.setEndTime(DateUtil.fomatDate(po.getEndTime(), DateUtil.YYYYMMDDHHMM));
                vo.setVisitorPhoneNo(po.getVisitorPhone());
                vo.setUrl(po.getUrl());
                vo = (AppGetVisitPassWordVO) StringHandlerUtil.formatString(vo);
                if (vo.getPassWord() == null || vo.getPassWord().isEmpty()) {
                    messageVO = new MessageVO(AppErrorCodeEnum.NO_DEVICE_AUTH.getErrorCode(), vo);
                } else {
                    messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), vo);
                }
            }else if(po.getResult().equals("TIME")){
                messageVO = new MessageVO(AppErrorCodeEnum.ADD_VISITOR_ERROR_2.getErrorCode());
            }else{
                Integer count = Integer.valueOf(po.getResult());
                if(count > 0) {
                    messageVO = new MessageVO(AppErrorCodeEnum.ADD_VISITOR_ERROR_3.getErrorCode(),
                            String.format("您当前剩余通行次数为%s次，仅能创建≤%s次通行次数，添加访客失败", po.getResult(), po.getResult()));
                }else{
                    messageVO = new MessageVO(AppErrorCodeEnum.ADD_VISITOR_ERROR_1.getErrorCode(),
                            String.format("您当前剩余通行次数为%s次，添加访客失败", po.getResult()));
                }
            }
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取通行密码失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      保存访客人脸
     * </desc>
     *
     * @param dto 接收数据dto类
     * @param sign 签名
     * @return
     * @author Qiang.S
     * @createDate 2019/02/26
     */
    @LoggerInfo(operateDesc = LogDescConstant.APP_GETVISITPASS_FACE)
    @RequestMapping(path = "/setVisitPassFace",method = RequestMethod.POST)
    @ResponseBody
    public Object setVisitPassFace(AppSetVisitPassFaceDTO dto, String sign){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(sign);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                dto = HttpProtocolUtil.parseRequestParamToDTO(AppSetVisitPassFaceDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }

            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",dto.getProjectId());
            params.put("imageType",dto.getImageType());
            params.put("passId",dto.getPassId());
            params.put("createTime",dto.getCreateTime());
            params.put("language",dto.getLanguage());
            if (flag) {
                params.put("imageStr",dto.getImageStr());
                if (!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(dto.getLanguage())?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(dto.getLanguage())?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }

            if (StringUtils.isBlank(dto.getImageStr())){
                return new MessageVO(AppErrorCodeEnum.IMAGE_DATA_INVALID.getErrorCode());
            }else if (StringUtils.isBlank(dto.getImageType())){
                dto.setImageType("png");
            }
            String uploadFilePath = uploadImageFile(dto.getImageStr(), dto.getImageType(), FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
            if (StringUtils.isBlank(uploadFilePath)) {
                return new MessageVO(AppErrorCodeEnum.IMAGE_UPLOAD_FAILED.getErrorCode());
            }
            Map<String, String> map = new HashMap<>();
            //判断项目是否开启人脸识别,并查询是否有百度库key
            OperateFaceApplyInfoVO operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(dto.getProjectId());
            if(operateFaceApplyInfoVO == null){
                ErrorCode errorCode = AppErrorCodeEnum.PROJECT_FACE_APPID_INEXISTENCE.getErrorCode();
                return new MessageVO(errorCode);
            }
            //访客人脸注册时,判断人脸库中是否有此人数据
            AppCreateBaiduFaceVO appCreateBaiduFaceVO = new AppCreateBaiduFaceVO();
            appCreateBaiduFaceVO.setAPP_ID(operateFaceApplyInfoVO.getAppId());
            appCreateBaiduFaceVO.setAPI_KEY(operateFaceApplyInfoVO.getApiKey());
            appCreateBaiduFaceVO.setSECRET_KEY(operateFaceApplyInfoVO.getSecretKey());
            appCreateBaiduFaceVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore()==0F?80F:operateFaceApplyInfoVO.getFaceScore());
//            String imageStr = URLDecoder.decode(dto.getImageStr(), "UTF-8");
//            appCreateBaiduFaceVO.setFile(new BASE64Decoder().decodeBuffer(imageStr));
            appCreateBaiduFaceVO.setImageUrl(uploadFilePath);
            String repeatResult = iIotBaiduFaceServiceClient.identifyUser(appCreateBaiduFaceVO);//拿到现有的id
            if (repeatResult != null && !"".equals(repeatResult)) {
                if ("error".equals(repeatResult)) {//调用接口异常
                    return new MessageVO(PropertyErrorCodeEnum.APPUSER_IDENTIFY_ERROR.getErrorCode());
                }
                if ("busy".equals(repeatResult)) {//调用接口忙
                    return new MessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode());
                }
            }
            String vFaceId;
            //判断认证图片是否重复
            if (repeatResult == null) {//人脸库中无此人脸ID使用V_ + pass_id
                appCreateBaiduFaceVO.setUid("V_"+dto.getPassId());
                //创建百度人脸信息
                boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
                if (!result) {
                    map.put("result","2");
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
                }
                vFaceId = appCreateBaiduFaceVO.getUid();
            }else {//人脸库中有此人脸
                //有此人脸时证明这个人在此项目中注册过人脸业主使用的是这个人的user_id,访客使用的是V_ + pass_id   不进行重复注册
                if (repeatResult.substring(0,2).equals("V_")) {//访客人脸则进行覆盖
                    appCreateBaiduFaceVO.setUid(repeatResult);
                    //创建百度人脸信息
                    boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
                    if (!result) {
                        map.put("result","2");
                        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
                    }
                }
                vFaceId = repeatResult;
            }
            iAppVisitorPassCodeRecordServiceClient.setVisitPassFace(dto.getPassId(), uploadFilePath, vFaceId, dto.getProjectId(), "",0);

            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            map.put("authDate",formatter.format(currentTime));
            map.put("result","1");
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(dto.getProjectId());
            // 平板优先离线，则插入同步数据
            if (projectPO.getOnOffLinePadFace() != null) {
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("3");
                padFaceSyncDataDTO.setProjectId(dto.getProjectId());
                padFaceSyncDataDTO.setPassId(dto.getPassId());
                padFaceSyncDataDTO.setStatus("1");
                padFaceSyncDataDTO.setSourceSystem(0);
                if(projectPO.getOnOffLinePadFace() == 1){
                    iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                }
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }

            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】保存访客人脸失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取访客通行密码记录
     * </desc>
     *
     * @param dto 接收数据dto类
     * @param sign 签名
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/30
     */
    @RequestMapping(path = "/getVisitorRecord",method = RequestMethod.POST)
    @ResponseBody
    public Object getVisitorRecord(AppGetVisitorRecordPageDTO dto,String sign){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(sign);http://shizuka.easy.echosite.cn
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                dto = HttpProtocolUtil.parseRequestParamToDTO(AppGetVisitorRecordPageDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(dto,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(dto,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(dto.getProjectId()) || !dto.getProjectId().matches("[0-9]{8}")){
                LOG.info("【APP_首页版块】获取访客通行密码记录_项目编号非法】"+dto.getProjectId());
                return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(dto.getToken());
            dto.setLoginUserId(userInfo.getUserId());
            //查询
            Page<AppGetVisitorRecordPageVO> page=iAppVisitorPassCodeRecordServiceClient.getPage(dto);
            page.getRows().forEach(pg->{
                pg=(AppGetVisitorRecordPageVO)StringHandlerUtil.formatString(pg);
            });
            Map<String,Object> map=new HashMap<>();
            map.put("list",page.getRows());
            map.put("pageCount",page.getPage().getTotalPage());
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取访客通行密码记录失败");
        }
        return messageVO;
    }


    /**
     * <desc>
     *     APP端_首页_获取APP的功能配置
     * </desc>
     * @param projectId
     * @param token
     * @param sign 签名
     * @return
     * @throws Exception
     * @author cuiduanwu
     * @createDate 2017/11/15
     */
    @ResponseBody
    @RequestMapping(path = "/appConfig",method = RequestMethod.POST)
    public Object appCheckConfig(String projectId,String token,String createTime, String sign,String language) throws Exception{
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验证签名
            Map<String,String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(createTime)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }else  if (StringUtils.isNotBlank(projectId)&&!projectId.matches("[0-9]{8}")){
                    return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }else if (StringUtils.isBlank(createTime)){
                    return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
                }else  if (StringUtils.isNotBlank(projectId)&&!projectId.matches("[0-9]{8}")){
                    return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
                }
            }
            List<String> moduleList = new ArrayList<>();
            List<AppFunctionInfoPO> appFunctionInfoPOs = iOperateAppFunctionInfoServiceClient.getAppConfig(projectId);
            if (appFunctionInfoPOs != null&&appFunctionInfoPOs.size()>0){
                for (AppFunctionInfoPO appFunctionInfoPO:appFunctionInfoPOs){
                    JSONObject js = new JSONObject();
                    moduleList.add(appFunctionInfoPO.getIdentifier());
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),moduleList);
        } catch (Exception e){
            throw new DataAccessException("【APP_首页版块_APP功能配置】获取APP功能配置失败",e);
        }
    }



    /**
     * <desc>
     *      获取所有项目id，包括禁用的项目
     * </desc>
     *
     * @param token
     * @param createTime 时间戳 参与签名
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/19
     */
    @RequestMapping(value = "/getAllProjects",method = RequestMethod.POST)
    @ResponseBody
    public Object getAllProjects(String token,String createTime,String sign,String language){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            List<String> list=iAppProjectServiceClient.getAllProjects(userInfo.getUserId());
            Map<String,Object> map=new HashMap<>();
            map.put("projects",list);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,map);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】获取所有项目id，包括禁用的项目",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取房屋申请记录。
     * <desc/>
     *
     * @param  projectId 项目编号
     * @param  pageNum 请求页码
     * @param  token 凭证
     * @param  createTime 时间
     * @param  sign 签名
     * @param  language
     * @return
     * @author shengen.T
     * @createDate 2018-03-27
     */
    @RequestMapping(value = "/homeApplyLog",method = RequestMethod.POST)
    @ResponseBody
    public Object getHomeApplyLog(String projectId,String pageNum,String token,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                pageNum = request.getAttribute("pageNum") == null ? null : request.getAttribute("pageNum").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("pageNum",pageNum);
            params.put("projectId",projectId);

            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }

            //判断请求页码
            if(StringUtils.isBlank(pageNum)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            Page<AppRoomApplyLogVO> pageVO = iAppHomeServiceClient.getApplyRoomLog(projectId,userInfo.getUserId(),pageNum);
            Map<String,Object> map=new HashMap<>();
            map.put("totalNum",pageVO.getPage().getTotalNumber());
            map.put("data",pageVO.getRows());
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取审核通过的房间列表",e);
        }
        return messageVO;
    }



    /**
     * <desc>
     *      预约呼梯。
     * <desc/>
     *
     * @param  callLiftDTO1 呼梯数据对象
     * @param  sign 凭证
     * @return
     * @author shengen.T
     * @createDate 2018-03-29
     */
    @LoggerInfo(operateDesc = LogDescConstant.CALL_ELEVATOR)
    @RequestMapping(value = "/cloudCallLift",method = RequestMethod.POST)
    @ResponseBody
    public Object callLift(AppCallLiftDTO callLiftDTO1, String sign) {
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(sign);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                callLiftDTO1 = HttpProtocolUtil.parseRequestParamToDTO(AppCallLiftDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            AppCallLiftDTO callLiftDTO = callLiftDTO1;
            //验证签名
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(callLiftDTO, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(callLiftDTO, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //判断设备唯一编号
            if (StringUtils.isBlank(callLiftDTO.getDeviceUnique())) {
                return new MessageVO(AppErrorCodeEnum.DEVICE_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            CloudElevatorVO vo = iAppDeviceServiceClient.getCallElevatorInfo(callLiftDTO.getDeviceUnique());
            //判断当前设备是否在线，如不在线返回失败
            String isOnline = iIotServerServiceClient.batchGetDeviceState(vo.getIotProductKey(),callLiftDTO.getDeviceUnique());
            //LOG.info(String.format("【云电梯在线状态%s】:%s",callLiftDTO.getDeviceUnique(),isOnline));
            if(isOnline ==null || (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType()))){
                return new MessageVO(AppErrorCodeEnum.CLOUD_ELEVATOR_OUT_LINE.getErrorCode());
            }
            //查询电梯设备是否绑定控制器
            Map<String,Object> controller = iAppDeviceServiceClient.getControllerDeviceUniqueByElevatorDeviceUnique(callLiftDTO.getDeviceUnique());
            //判断群控器是否在线
            if(controller != null && controller.get("groupConId") != null){
                isOnline = iIotServerServiceClient.batchGetDeviceState(controller.get("iotProductKey").toString(),controller.get("groupConId").toString());
                //LOG.info(String.format("【云群控器在线状态%s】:%s",controller.get("groupConId").toString(),isOnline));
                if(isOnline ==null || (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType()))){
                    return new MessageVO(AppErrorCodeEnum.CLOUD_ELEVATOR_OUT_LINE.getErrorCode());
                }
            }
            //判断楼层
            Map result = StringHandlerUtil.checkFloor(callLiftDTO.getFromId(), callLiftDTO.getToId(), PlatformConstants.MAX_FLOOR_NUM);
            if (!"0".equals(result.get("code").toString())) {
                return new MessageVO(AppErrorCodeEnum.ELEVATOR_FLOOR_ERROR.getErrorCode(), result.get("message"));
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(callLiftDTO.getToken()));
            //电梯设备信息
            List<AppFloorDevicesVO> floors = iAppDeviceServiceClient.getFloorDevices(userInfo.getUserId(), userInfo.getCurrentProjectId(), 0);
            // 获取游客模式下有公共楼层的电梯设备
            List<AppFloorDevicesVO> floorGuestList = iAppDeviceServiceClient.getGuestFloorList(StringHandlerUtil.getProjectIdByDeviceUnique(callLiftDTO.getDeviceUnique()));
            List<String> floorDeviceUniqueList = new ArrayList<>();
            for (AppFloorDevicesVO appFloorDevicesVO : floors) {
                floorDeviceUniqueList.add(appFloorDevicesVO.getDeviceUnique());
            }
            for (AppFloorDevicesVO appFloorDevicesVO : floorGuestList) {
                if (!floorDeviceUniqueList.contains(appFloorDevicesVO.getDeviceUnique())) {
                    floors.add(appFloorDevicesVO);
                    floorDeviceUniqueList.add(appFloorDevicesVO.getDeviceUnique());
                }
            }
            if ((floors != null) && (floors.size() > 0)) {
                Optional<AppFloorDevicesVO> floorInfo = floors.stream().filter(floor -> callLiftDTO.getDeviceUnique().equals(floor.getDeviceUnique())).findFirst();
                if (floorInfo.isPresent()) {
                    List<String> validFloor = new ArrayList<>(); //合法楼层
                    //常用楼层
                    List<String> liveFloorList = StringHandlerUtil.splitStringList(floorInfo.get().getLiveFloor());
                    if ((liveFloorList != null) && (liveFloorList.size() > 0)) {
                        validFloor = liveFloorList.stream().filter(liveFloor -> (liveFloor.equals(callLiftDTO.getFromId()) || liveFloor.equals(callLiftDTO.getToId()))).collect(Collectors.toList());
                    }
                    //公共楼层
                    List<String> commonFloorList = StringHandlerUtil.splitStringList(floorInfo.get().getCommonFloor());
                    if ((commonFloorList != null) && (commonFloorList.size() > 0)) {
                        List<String> tmp = commonFloorList.stream().filter(commonFloor -> (commonFloor.equals(callLiftDTO.getFromId()) || commonFloor.equals(callLiftDTO.getToId()))).collect(Collectors.toList());
                        validFloor.addAll(tmp);
                    }
                    if ((validFloor != null) && (validFloor.size() < 2)) {
                        return new MessageVO(AppErrorCodeEnum.FLOOR_NOT_VALID_ERR.getErrorCode());
                    }
                } else {
                    //该用户该电梯设备信息
                    LOG.info(String.format("该用户无该电梯设备信息，用户Id：%s 项目编号：%s 设备编号：%s", userInfo.getUserId(), userInfo.getCurrentProjectId(), callLiftDTO.getDeviceUnique()));
                    return new MessageVO(AppErrorCodeEnum.CLOUD_ELEVATOR_OUT_LINE.getErrorCode());
                }
            } else {
                //该用户无任何设备信息
                LOG.info(String.format("该用户无任何电梯设备信息，用户Id：%s 项目编号：%s", userInfo.getUserId(), userInfo.getCurrentProjectId()));
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
            }
            //取真实楼层
            AppElevatorFloorSimpleVO simpleVO = iAppHomeServiceClient.getRealFloorInfo(callLiftDTO.getDeviceUnique(), callLiftDTO.getFromId(), callLiftDTO.getToId());
            if (simpleVO == null) {
                LOG.info(String.format("【首页_预约呼梯】楼层号信息有误，设备号：%s 出发楼层：s%  目标楼层：s%", callLiftDTO.getDeviceUnique(), callLiftDTO.getFromId(), callLiftDTO.getToId()));
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
            }
            String snr = LogicIdUtil.bussinessId();
            if(null != controller && null != controller.get("deviceUnique") ) {
                String userLabel = iAppDeviceServiceClient.getUserLabel(userInfo.getUserId(), StringHandlerUtil.getProjectIdByDeviceUnique(callLiftDTO.getDeviceUnique()));
                if(StringUtils.isBlank(userLabel) || !userLabel.contains("1")) {
                    Boolean isVipCall = iAppDeviceServiceClient.getIsVipCall(callLiftDTO.getDeviceUnique());
//                    LOG.info("是否处于vip呼梯中》》》》》》》》》》》》》》》》》》" + isVipCall);
                    if(isVipCall) {
                        return new MessageVO(BaseErrorCodeEnum.ELEVATOR_CALL_ERR.getErrorCode());
                    }
                }
            }

            //调用IOT呼梯
            iAppDeviceServiceClient.cloudElevatorCall(
                    callLiftDTO.getDeviceUnique(),
                    CloudElevatorSourceEnum.ITLONG_CLOUD_ELEVATOR.getDescription(),
                    simpleVO.getRealFrom(),simpleVO.getRealTo(),null, CloudElevatorCallTypeEnum.OUT.getType(),null,
                    CallElevatorSourceTypeEnum.APP.getType(),null,snr,null, null, null, userInfo.getUserId(), "");
            //装配呼梯记录对象
            AppCallLiftSaveDTO saveDTO = new AppCallLiftSaveDTO();
            saveDTO.setUserId(userInfo.getUserId());
            if(controller != null && controller.get("groupConId") != null){
                saveDTO.setGroupConId(controller.get("groupConId").toString());
            }
            saveDTO.setDeviceUnique(callLiftDTO.getDeviceUnique());
            saveDTO.setFromFloor(callLiftDTO.getFromId());
            saveDTO.setToFloor(callLiftDTO.getToId());
            saveDTO.setProjectId(userInfo.getCurrentProjectId());
            saveDTO.setSource(CallElevatorRecordSourceEnum.JIAR.getType());
            saveDTO.setSource(1);
            saveDTO.setFromFloor(callLiftDTO1.getFromId());
            saveDTO.setToFloor(callLiftDTO1.getToId());
            iAppHomeServiceClient.saveCallLiftRecord(saveDTO);
            Map<String, Object> returnData = new HashMap<>();
            returnData.put("deviceUnique", callLiftDTO.getDeviceUnique());
            returnData.put("fromId", callLiftDTO.getFromId());
            returnData.put("fromNum", simpleVO.getFromFloor());
            returnData.put("toId", callLiftDTO.getToId());
            returnData.put("toNum", simpleVO.getToFloor());
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), returnData);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】预约呼梯", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      取消预约呼梯。
     * <desc/>
     *
     * @param  deviceUnique 设备唯一编码
     * @param  token 凭证
     * @param  createTime 时间
     * @param  sign 签名
     * @param  language  语言
     * @return
     * @author shengen.T
     * @createDate 2018-04-09
     */
    @LoggerInfo(operateDesc = LogDescConstant.CALL_OFF_ELEVATOR)
    @RequestMapping(value = "/cancelCallLift",method = RequestMethod.POST)
    @ResponseBody
    public Object cancelCallLift(String deviceUnique,String token,String createTime,String sign,String language){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("deviceUnique",deviceUnique);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //判断设备唯一编号
            if(StringUtils.isBlank(deviceUnique)){
                return new MessageVO(AppErrorCodeEnum.DEVICE_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            //取消预约呼梯
            iAppHomeServiceClient.cancelCallLift(userInfo.getUserId(),userInfo.getCurrentProjectId(),deviceUnique);

            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】取消预约呼梯",e);
        }
        return messageVO;
    }
    /**
     * <desc>
     *      获取呼梯记录。
     * <desc/>
     *
     * @param  token 凭证
     * @param  language 语言类型
     * @param  createTime 时间
     * @param deviceUnique 设备唯一ID
     * @param sign 签名
     * @return
     * @author shengen.T
     * @createDate 2018-04-02
     */
    @RequestMapping(value = "/liftMark",method = RequestMethod.POST)
    @ResponseBody
    public Object getCallLiftRecord(String token,String language,String createTime,String deviceUnique,String sign){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("deviceUnique",deviceUnique);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            List<AppCallElevatorRecordVO> recordVO = iAppHomeServiceClient.getCallElevatorRecord(userInfo.getUserId(),deviceUnique);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),recordVO);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取预约呼梯列表",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      删除呼梯记录。
     * <desc/>
     *
     * @param  token 凭证
     * @param  language 语言类型
     * @param  createTime 时间
     * @param  deviceUnique 设备唯一ID
     * @param  sign 签名
     * @return
     * @author shengen.T
     * @createDate 2018-04-04
     */
    @LoggerInfo(operateDesc = LogDescConstant.DELETE_CALL_ELEVATOR)
    @RequestMapping(value = "/deleteLiftMark",method = RequestMethod.POST)
    @ResponseBody
    public Object deleteCallLiftRecord(String token,String language,String createTime,String deviceUnique,String sign){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("deviceUnique",deviceUnique);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            iAppHomeServiceClient.deleteCallElevatorRecord(userInfo.getUserId(),userInfo.getCurrentProjectId(),deviceUnique);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取预约呼梯列表",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取电梯时时状态。
     * <desc/>
     *
     * @param token 凭证
     * @param language 语言
     * @param createTime 时间
     * @param deviceUnique 设备唯一码列表
     * @param sign 签名
     * @return
     * @author shengen.T
     * @createDate 2018-04-11
     */
    @RequestMapping(value = "/liftState",method = RequestMethod.POST)
    @ResponseBody
    public Object getElevatorOftenStatus(String token,String language,String createTime,String deviceUnique,String sign){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("deviceUnique",deviceUnique);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            deviceUnique = URLDecoder.decode(deviceUnique, "UTF-8");
            //获取设备编号列表
            String[]  deviceUniqueArr = StringHandlerUtil.splitString(deviceUnique);
            if((deviceUniqueArr==null)||(deviceUniqueArr.length<1)){
                return new MessageVO(AppErrorCodeEnum.DEVICE_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            List<AppCloudElevatorRunState> eleRunStatesVO = iAppDeviceServiceClient.getCloudElevatorState(deviceUnique,userInfo.getUserId());
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),eleRunStatesVO);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取电梯时时状态",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      平板设备验证。
     * <desc/>
     *
     * @param type 设备类型；1为梯控，2门禁
     * @param projectId 项目ID
     * @param deviceId 设备机号
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path ="/deviceVerify",method = RequestMethod.POST)
    @ResponseBody
    public Object deviceVerify(String type, String projectId,String deviceId, String createTime,String sign,String language) {
        MessageVO messageVO = new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(),false);
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                type = request.getAttribute("type") == null ? null : request.getAttribute("type").toString();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                deviceId = request.getAttribute("deviceId") == null ? null : request.getAttribute("deviceId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("type",type);
            params.put("projectId",projectId);
            params.put("deviceId",deviceId);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
                //判断必要信息是否为空
                else if (StringUtils.isBlank(type)||StringUtils.isBlank(createTime)|| StringUtils.isEmpty(projectId) || StringUtils.isEmpty(language) || StringUtils.isEmpty(deviceId)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
                //判断必要信息是否为空
                else if (StringUtils.isBlank(type)||StringUtils.isBlank(createTime)|| StringUtils.isEmpty(projectId) || StringUtils.isEmpty(language) || StringUtils.isEmpty(deviceId)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            int i = 0;
            // 梯控
            if ("1".equals(type)) {
                i = iAppHomeServiceClient.elevatorAuthorityCheck(projectId,deviceId);
            }
            //门禁
            else if ("2".equals(type)) {
                i = iAppHomeServiceClient.entranceAuthorityCheck(projectId,deviceId);
            }

            if (i > 0) {
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),true);
            }

        } catch (Exception e) {
            throw new DataAccessException("【App_deviceVerify】设备验证失败", e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      平板登陆验证(工程人员)。
     * <desc/>
     *
     * @param ID 帐号
     * @param password 登陆密码
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path ="/engineerLoginVerify",method = RequestMethod.POST)
    @ResponseBody
    public Object engineerLoginVerify(String ID, String password,String createTime,String sign,String language) {
        MessageVO messageVO = new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(),false);
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                ID = request.getAttribute("ID") == null ? null : request.getAttribute("ID").toString();
                password = request.getAttribute("password") == null ? null : request.getAttribute("password").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("ID",ID);
            params.put("password",password);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
                //判断必要信息是否为空
                else if (StringUtils.isBlank(ID)||StringUtils.isBlank(createTime)|| StringUtils.isEmpty(password) || StringUtils.isEmpty(language)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
                //判断必要信息是否为空
                else if (StringUtils.isBlank(ID)||StringUtils.isBlank(createTime)|| StringUtils.isEmpty(password) || StringUtils.isEmpty(language)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            int i = 0;
            i = iAppHomeServiceClient.engineerLoginVerify(ID,password);

            if (i > 0) {
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),true);
            }

        } catch (Exception e) {
            throw new DataAccessException("【App_loginVerify】登陆验证失败", e);
        }
        return  messageVO;
    }


    /**
     * <desc>
     *      人脸识别扣费。
     * <desc/>
     *
     * @param  paymentDTO
     * @param  sign 签名
     * @return
     * @author shengen.T
     * @createDate 2018-05-14
     */
    @RequestMapping(value = "/payment",method = RequestMethod.POST)
    @ResponseBody
    public Object faceRecognitionPayment(AppFaceRecognitionPaymentDTO paymentDTO,String sign){
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(sign);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                paymentDTO = HttpProtocolUtil.parseRequestParamToDTO(AppFaceRecognitionPaymentDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(paymentDTO,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(paymentDTO,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //判断项目编号
            if(StringUtils.isBlank(paymentDTO.getProjectId()) || !paymentDTO.getProjectId().matches("[0-9]{8}")){
                return new MessageVO(AppErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //判断人脸ID
            if(StringUtils.isBlank(paymentDTO.getUId())){
                return new MessageVO(AppErrorCodeEnum.FACE_ID_EMPTY_ERROR.getErrorCode());
            }
            //判断设备类型
            if(StringUtils.isBlank(paymentDTO.getType()) || ((!"1".equals(paymentDTO.getType()))&&(!"2".equals(paymentDTO.getType())))){
                return new MessageVO(AppErrorCodeEnum.DEVICE_TYPE_INVALID_ERR.getErrorCode());
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】人脸认证扣费失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取当前用户下所有项目的UI信息
     * <desc/>
     *
     * @param token 凭证
     * @param language 语言
     * @param createTime 时间
     * @param deviceType UI类型，1-ios系统，2-安卓系统，3-物业
     * @param sign 签名
     * @return
     * @author JuGuang.S
     * @createDate 2018-05-24
     */
    @RequestMapping(value = "/getProjectIdUi",method = RequestMethod.POST)
    @ResponseBody
    public Object getProjectIdUi(String token,String language,String createTime,String deviceType,String sign){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                deviceType = request.getAttribute("deviceType") == null ? null : request.getAttribute("deviceType").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("deviceType",deviceType);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }

            //从缓存中获取用户信息
            AppUserCacheVO userInfo=(AppUserCacheVO)StringHandlerUtil.formatString(userCache.retrieve(token));
            List<AppUserOwnProjectVO> projectList = userInfo.getProjects();

            if(projectList==null || projectList.size() == 0){
                return new MessageVO(AppErrorCodeEnum.USER_NOT_PROJECT.getErrorCode());
            }

            Set<String> projectIdSet = new HashSet<>();
            for(AppUserOwnProjectVO projectVO : projectList){
                projectIdSet.add(projectVO.getProjectId());
            }
            String projectIds = String.join(",",projectIdSet);
            List<AppGetProjectUiVO> appGetProjectUiVOList = iAppProjectServiceClient.getProjectIdUi(projectIds,deviceType);

            List<Map<String,Object>> list = new ArrayList<>();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for(AppGetProjectUiVO uiVO : appGetProjectUiVOList){
                Map<String,Object> map = new HashMap<>();
                map.put("projectId",uiVO.getProjectId());
                if(uiVO.getUpdateTime()==null){
                    map.put("versionTime",simpleDateFormat.format(uiVO.getCreateTime()));
                }else {
                    map.put("versionTime",simpleDateFormat.format(uiVO.getUpdateTime()));
                }
                map.put("uiUrl",uiVO.getUiUrl());
                map.put("fileName",uiVO.getUiUrl().substring(uiVO.getUiUrl().lastIndexOf("/")+1));
                list.add(map);
            }

            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),list);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】获取当前用户下所有项目的UI信息异常",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      app用户开门操作
     * <desc/>
     *
     * @param sipAccount sip帐号
     * @param message 指令相关信息
     * @return
     * @author Qiang.S
     * @createDate 2018-09-12
     */
    @LoggerInfo(operateDesc = LogDescConstant.CLOUD_TALK_TCP_OPEN_DOOR)
    @RequestMapping(value = "/appOpenDoor",method = RequestMethod.POST)
    @ResponseBody
    public Object appOpenDoor(String token,String language, String createTime, String sipAccount, String message, String sign) {
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                sipAccount = request.getAttribute("sipAccount") == null ? null : request.getAttribute("sipAccount").toString();
                message = request.getAttribute("message") == null ? null : request.getAttribute("message").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("sipAccount",sipAccount);
            params.put("message",message);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(sipAccount) || StringUtils.isEmpty(message)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            String userId = UserTokenUtil.newAPPTokenDecrypt(token, APP_USER_TOKEN_KEY);
            String deviceUnique = iCloudIntercomServiceClient.getDeviceUniqueBySip(sipAccount);
            //iot不在线走tcp
            if (redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY+deviceUnique) == null ||
                    !redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY+deviceUnique).equals("2")) {
//                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),itcpServiceClient.sendMessage(userId,sipAccount,message,10));
                return new MessageVO(AppErrorCodeEnum.CLOUD_TALK_IS_NOT_ONLINE_ERROR.getErrorCode());
            } else {//iot在线
                iCloudIntercomServiceClient.iotOpenDoor(userId,sipAccount,message,"1");
                int count = 0;
                AppTCPResultVO appTCPResultVO = new AppTCPResultVO();
                appTCPResultVO.setDataFlag("1");
                while(count<10){
                    Thread.sleep(500);
                    IotCloudIntercomStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE +
                            deviceUnique),IotCloudIntercomStateDTO.class);
                    if(dto != null && dto.getMsgCode() == 0){
                        appTCPResultVO.setDataFlag("0");
                        redisService.del(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE +deviceUnique);
                        break;
                    }
                    count++;
                }
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),appTCPResultVO);
            }
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】开门异常", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      app切换音视频
     * <desc/>
     *
     * @param videoState 0：音视频1音频
     * @param sipAccount sip帐号
     * @return
     * @author Qiang.S
     * @createDate 2018-09-12
     */
    @LoggerInfo(operateDesc = LogDescConstant.SWITCH_VIDEO)
    @RequestMapping(value = "/switchVideo",method = RequestMethod.POST)
    @ResponseBody
    public Object switchVideo(String videoState, String language, String createTime, String sipAccount, String sign) {
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                videoState = request.getAttribute("videoState") == null ? null : request.getAttribute("videoState").toString();
                sipAccount = request.getAttribute("sipAccount") == null ? null : request.getAttribute("sipAccount").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("sipAccount",sipAccount);
            params.put("videoState",videoState);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(sipAccount) || StringUtils.isBlank(videoState)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            String deviceUnique = iCloudIntercomServiceClient.getDeviceUniqueBySip(sipAccount);
            //iot不在线走tcp
            if (redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY+deviceUnique) == null ||
                    !redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY+deviceUnique).equals("2")) {
//                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),itcpServiceClient.sendMessage("",sipAccount,videoState, 11));
                return new MessageVO(AppErrorCodeEnum.CLOUD_TALK_IS_NOT_ONLINE_ERROR.getErrorCode());
            }else {//iot在线
                iCloudIntercomServiceClient.switchVideo(sipAccount,videoState);
                int count = 0;
                AppTCPResultVO appTCPResultVO = new AppTCPResultVO();
                appTCPResultVO.setDataFlag("1");
                appTCPResultVO.setVideoState("");
                while(count<10){
                    Thread.sleep(500);
                    IotCloudIntercomStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE +
                            deviceUnique),IotCloudIntercomStateDTO.class);
                    if(dto != null && dto.getMsgCode() == 0){
                        appTCPResultVO.setDataFlag("0");
                        appTCPResultVO.setVideoState(dto.getVideoState());
                        redisService.del(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE +deviceUnique);
                        break;
                    }
                    count++;
                }
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),appTCPResultVO);
            }
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】切换音视频异常", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      iot开门
     * </desc>
     *
     * @param deviceUnique 设备序列号
     * @param token 用户凭证
     * @param createTime 时间戳 参与签名
     * @param sign 签名
     * @param language 语言
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/04
     */
    @ResponseBody
    @RequestMapping("/netOpenDoor")
    @LoggerInfo(operateDesc = LogDescConstant.REMOTE_OPEN_DOOR)
    public Object netOpenDoor(String deviceUnique,String correlationId,String token,String createTime,String sign,String language) throws Exception{
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
                correlationId = request.getAttribute("correlationId") == null ? null : request.getAttribute("correlationId").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            Map<String,String> params = new HashMap<>();
            params.put("deviceUnique",deviceUnique);
            params.put("correlationId",correlationId);
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //查询项目远程开门配置是否为启用 关闭则直接返回
            Integer networkOpen = iAppProjectServiceClient.getNetworkOpenSetting(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            if(DataStatusEnum.DELETE.getType()==networkOpen){
                return new MessageVO(AppErrorCodeEnum.CLOUD_ENTRANCE_NETWORK_OPEN_IS_CLOSED.getErrorCode());
            }
            //查询门禁设备的iot账号及绑定的iot产品key
            Map<String,Object> entrance = iCloudEntranceServiceClient.getMainDeviceUniqueAndProductKey(deviceUnique);
            Map<String,Object> result = new HashMap<>();
            if(entrance != null && entrance.get("deviceUnique") != null) {
                //判断当前设备是否在线，如不在线返回失败
                String isOnline = iIotServerServiceClient.batchGetDeviceState(entrance.get("productKey").toString(),entrance.get("deviceUnique").toString());
                if(isOnline == null || (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType()))){
                    result.put("doorStatus",0);
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
                }
                AppUserCacheVO userInfoPO = userCache.retrieve(token);
                iCloudEntranceServiceClient.entranceOpenOrCloseCtrl("itlong", entrance.get("deviceUnique").toString(),
                        Integer.valueOf(deviceUnique.substring(deviceUnique.length() - 4, deviceUnique.length())).toString(),
                        CloudEntranceOpenTypeEnum.OPEN.getType().toString(), "1", entrance.get("productKey").toString(), userInfoPO.getUserId(), correlationId,"0");
                //判断当前状态是否是开门，如果是开门则返回成功，否则返回失败
                int doorStatus = 2;
                int count = 0;
                while(count<10){
                    Thread.sleep(500);
                    IotCloudEntranceStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_ENTRANCE_STATE_CACHE +
                            deviceUnique),IotCloudEntranceStateDTO.class);
//                            (IotCloudEntranceStateDTO) redisService.decodeObject(RedisConstant.REDIS_IOT_CLOUD_ENTRANCE_STATE_CACHE +
//                                    deviceUnique, new TypeReference<IotCloudEntranceStateDTO>() {
//                            });
                    if(dto != null && dto.getMsgCode() == 0){
                        doorStatus = 1;
                        break;
                    }
                    count++;
                }
                result.put("doorStatus", doorStatus);
            }else{
                result.put("doorStatus",0);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
        }catch (Exception e){
            throw new DataAccessException("【APP_首页版块】远程开门失败",e);
        }
    }

    /**
     * <desc>
     *      获取用户当前项目下的推送消息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @createDate 2019/05/30
     * @author wangzhi
     */
    @ResponseBody
    @PostMapping("messageBox")
    public Object getMessage(String projectId, String pageNum, String msgType, String token, String createTime, String sign, String language, String version) {
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                pageNum = request.getAttribute("pageNum") == null ? null : request.getAttribute("pageNum").toString();
                msgType = request.getAttribute("msgType") == null ? null : request.getAttribute("msgType").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
                version = request.getAttribute("version") == null ? null : request.getAttribute("version").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("pageNum",pageNum);
            params.put("msgType",msgType);
            params.put("createTime",createTime);
            params.put("language",language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return  new MessageVO(errorCode);
                }
            } else {
                params.put("version",version);
                if (!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode(): AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return  new MessageVO(errorCode);
                }
            }

            if (StringUtils.isBlank(projectId) || StringUtils.isBlank(pageNum) || StringUtils.isBlank(msgType) || StringUtils.isBlank(token)) {
                return new MessageVO(LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            String url = PROPERTY_MANAGE_WEB_URL + "pushInfo?";
            Map<String, Object> data = iAppProjectServiceClient.getMessageBox(projectId, pageNum, msgType, userInfo.getUserId(), url, version);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.SUCCESS.getErrorCode() : BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            return new MessageVO(errorCode, data);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】获取用户当前项目下的推送消息失败", e);
        }
    }

    /**
     * <desc>
     *      用户读取新消息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @createDate 2019/05/30
     * @author wangzhi
     */
    @ResponseBody
    @PostMapping("readNewMsg")
    public Object readNewMsg(String msgId, String token, String createTime, String sign, String language) {
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                msgId = request.getAttribute("msgId") == null ? null : request.getAttribute("msgId").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("msgId", msgId);
            params.put("createTime", createTime);
            params.put("language", language);
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }

            if (StringUtils.isBlank(msgId) || StringUtils.isBlank(token)) {
                return new MessageVO(LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            iAppProjectServiceClient.readNewMsg(msgId, userInfo.getUserId());
            Map<String, String> data = new HashMap<>();
            data.put("readCode", "1");
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.SUCCESS.getErrorCode() : BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            return new MessageVO(errorCode, data);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】用户读取新消息失败", e);
        }
    }

    /**
     * <desc>
     *      获取启动页
     * <desc/>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018-09-12
     */
    @RequestMapping(value = "/StartAdvertising",method = RequestMethod.POST)
    @ResponseBody
    public Object StartAdvertising(String language, String createTime, String sign) {
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            OperateAppHomePageGetPageVO vo = iOperateAppHomePageServiceClient.StartAdvertising();
            Map<String, String> map = new HashMap<>();
            map.put("image", vo.getImageUrl());
            map.put("updateTime", vo.getUpdateTime());
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), map);
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】获取启动页异常", e);
        }
    }

    /**
     * <desc>
     *      获取广告(运营活动)
     * <desc/>
     *
     * @param projectId 项目编号
     * @return
     * @author Qiang.S
     * @createDate 2019-06-25
     */
    @RequestMapping(value = "/OperationalAdvertising",method = RequestMethod.POST)
    @UnAuthAccessRequired
    @ResponseBody
    public Object OperationalAdvertising(String projectId, String language, String createTime, String sign) {
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            params.put("language",language);
            //验证签名
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(projectId)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            List<OperateActivitiesGetPageVO> list = iOperateActivitiesServiceClient.OperationalAdvertising(projectId);
            List<Map<String, String>> activitiesInfo = new ArrayList<>();
            for (OperateActivitiesGetPageVO vo : list) {
                Map<String, String> map = new HashMap<>();
                map.put("image",vo.getImageUrl());
                map.put("activitiesName",vo.getActivitiesName());
                map.put("content",vo.getContent());
                map.put("skipUrl",vo.getSkipUrl());
                map.put("skipFlag",vo.getSkipFlag());
                activitiesInfo.add(map);
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),activitiesInfo);
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】获取广告异常", e);
        }
    }

     /**
     * <desc>
     *      上传图片文件
     * <desc/>
     *
     * @param imageStr 图片二进制
     * @param imageType 图片类型
     * @return
     * @author Qiang.S
     * @createDate 2018-05-07
     */
    private String uploadImageFile(String imageStr,String imageType, FileCatalogEnum fileCatalog){
        try {
            imageStr = URLDecoder.decode(imageStr, "UTF-8");
        }catch (Exception e){
            LOG.info("imageStr URLDecoder失败", e);
            return null;
        }
        byte[] bytes = null;
        try {
            bytes = new BASE64Decoder().decodeBuffer(imageStr);
        } catch (IOException e) {
            LOG.info("BASE64Decoder().decodeBuffer失败,imageStr不合法", e);
            return null;
        }
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                byteArrayInputStream,
                imageType,
                FILE_ACCESS_URL,
                fileCatalog.getType()
        );
        try {
            //LOG.info("正在上传图片");
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            //LOG.info("图片上传完毕");
            String returnCode = resultMap.get("returnCode").toString();
            if ("true".equals(returnCode)){
                String fileUrl = resultMap.get("accessPath").toString();
                return fileUrl;
            }else {
                LOG.info(String.format("图片上传失败，returnCode: %s",returnCode));
                return null;
            }
        } catch (IOException e) {
            LOG.info("UploadFileUtil.uploadFile失败", e);
            return null;
        }
    }

    /**
     * <desc>
     *      上传常用楼层
     * </desc>
     *
     * @param projectId 项目编号
     * @param deviceUnique 设备序列号
     * @param loadDeviceOrder 常用楼层名称
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/10/08
     */
    @ResponseBody
    @PostMapping(path = "upliveChoiceFloor")
    @LoggerInfo(operateDesc = LogDescConstant.UPLOAD_CHOICE_FLOOR_DESC)
    public Object uploadChoiceFloor(String projectId, String deviceUnique, String loadDeviceOrder,String loadPublicOrder, String token, String language, String createTime, String sign) {
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                deviceUnique = request.getAttribute("deviceUnique") == null ? null : request.getAttribute("deviceUnique").toString();
                loadDeviceOrder = request.getAttribute("loadDeviceOrder") == null ? "" : request.getAttribute("loadDeviceOrder").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                loadPublicOrder = request.getAttribute("loadPublicOrder") == null ? "" : request.getAttribute("loadPublicOrder").toString();

            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("deviceUnique", deviceUnique);
            params.put("loadDeviceOrder", loadDeviceOrder);
            params.put("loadPublicOrder", loadPublicOrder);
            params.put("language", language);
            params.put("createTime", createTime);
            //验证签名
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(projectId) || StringUtils.isBlank(deviceUnique) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = userCache.retrieve(token);
            iAppProjectServiceClient.uploadChoiceFloor(projectId, deviceUnique, loadDeviceOrder, userInfo.getUserId(),loadPublicOrder);
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            //查询用户是否有人脸，有则将组装数据下发至人脸识别系统
            String facePicUrl = iPadFaceSyncDataServiceClient.getFacePicUrl(userInfo.getUserId(),projectId);
            if (projectPO.getOnOffLinePadFace() != null && StringUtils.isNotEmpty(facePicUrl)) {
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("1");
                padFaceSyncDataDTO.setAppUserIds(userInfo.getUserId());
                padFaceSyncDataDTO.setProjectId(projectId);
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }
            //组装云对讲同步指令
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            JSONObject json = new JSONObject();
            json.put("userId", userInfo.getUserId());
            json.put("projectId", projectId);
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json,projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",changeLogPOS);
            //发送云对讲指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY
            );
         //发送平板指令
            //推送平板增量数据
            List<Map<String,Object>> padDatas = iPropertyHouseHoldInfoServiceClient.getUserRoomIdsByUserIdAndProjectId(
                    StringHandlerUtil.splitString(userInfo.getUserId()),projectId
            );
            //发送平板指令
            List<PadUserAuthPushDTO> dtos = new ArrayList<>();
            Map<String,Object> padMessage = new HashMap<>();
            for(Map<String,Object>  padData : padDatas){
                PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
                dto.setProjectId(projectId);
                dto.setRoomId(padData.get("roomId").toString());
                dto.setUserId(padData.get("userId").toString());
                dto.setPushType(PadChangeBusinessEnum.PUSH_USER.getCommandType());
                //修改App用户信息接口
                dto.setInstructionType(15);
                dto.setSourceSystem(2);
                dtos.add(dto);
            }

            padMessage.put("data",JsonUtil.toJSON(dtos));
            messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE,
                    JsonUtil.toJSON(padMessage), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);



            //发送云门禁指令
            JSONObject jsonEntrance = new JSONObject();
            jsonEntrance.put("userId", userInfo.getUserId());
            jsonEntrance.put("projectId",projectId);
            // 云门禁
            List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
            changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, jsonEntrance,projectId));

            JSONObject dataJsEntrance = new JSONObject();
            dataJsEntrance.put("data", changeEntranceLogPOS);
            //发送云门禁指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJsEntrance),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】上传常用楼层失败", e);
        }
    }

    /**
     * <desc>
     *      获取当前用户临时权限设备列表
     * </desc>
     *
     * @param token
     * @param createTime 时间戳参与签名
     * @return
     * @author Juguang.S
     * @createDate 2019/09/02
     */
    @RequestMapping(value = "/getVisitorDeviceList",method = RequestMethod.POST)
    @ResponseBody
    public Object getUserTemporaryAuthDeviceList(String token,String createTime,String sign,String language,String projectId){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("projectId",projectId);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(token);

            //获取当前用户临时权限
            List<AppUserDevicesVO> deviceList = iAppDeviceServiceClient.getUserDevicesInfo(userInfo.getUserId(), projectId);

            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,deviceList);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】添加访客获取用户临时权限设备列表失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      创建访客时创建或修改标签
     * </desc>
     *
     * @param deviceMarkDTO 创建或修改标签的信息
     * @return
     * @author Juguang.S
     * @createDate 2019/09/02
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.CREATE_OR_UPDATE_DEVEICE_MARKS_INFO)
    @RequestMapping(value = "/createDeviceMark",method = RequestMethod.POST)
    public Object createDeviceMark(CreateDeviceMarkDTO deviceMarkDTO,String sign){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(sign);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                deviceMarkDTO = HttpProtocolUtil.parseRequestParamToDTO(CreateDeviceMarkDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",deviceMarkDTO.getCreateTime());
            params.put("language",deviceMarkDTO.getLanguage());
            params.put("projectId",deviceMarkDTO.getProjectId());
            params.put("markId",deviceMarkDTO.getMarkId());
            params.put("markName",deviceMarkDTO.getMarkName());
            params.put("deviceUniques",deviceMarkDTO.getDeviceUniques());
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(deviceMarkDTO.getLanguage())?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(deviceMarkDTO.getLanguage())?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(deviceMarkDTO.getToken());
            deviceMarkDTO.setLoginUserId(userInfo.getUserId());
            Map<String,String> map = new HashMap<>();
            map.put("markId",iAppDeviceServiceClient.saveOrUpdateDeviceMark(deviceMarkDTO));
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(deviceMarkDTO.getLanguage())?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,map);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】创建访客时创建或修改标签失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      自动切换小区
     * </desc>
     *
     * @param token 身份令牌
     * @param longitude 经度
     * @param latitude 纬度
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/10/11
     */
    @ResponseBody
    @PostMapping(path = "autoMatchProject")
    public Object autoMatchProject(String token, String longitude, String latitude, String language, String createTime, String sign){
        try {
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                longitude = request.getAttribute("longitude") == null ? null : request.getAttribute("longitude").toString();
                latitude = request.getAttribute("latitude") == null ? null : request.getAttribute("latitude").toString();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("longitude",longitude);
            params.put("latitude",latitude);
            params.put("language",language);
            params.put("createTime",createTime);
            //验证签名
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            if (StringUtils.isBlank(longitude) || StringUtils.isBlank(latitude) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 从缓存中获取用户信息
            AppUserCacheVO userInfo = userCache.retrieve(token);
            Map<String, Object> data = iAppProjectServiceClient.autoMatchProject(longitude, latitude, userInfo.getUserId());
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】自动切换小区失败",e);
        }
    }

    /**
     * <desc>
     *      获取当前用户的设备标签
     * </desc>
     *
     * @param token
     * @param createTime 时间戳参与签名
     * @return
     * @author Juguang.S
     * @createDate 2019/09/02
     */
    @ResponseBody
    @RequestMapping(value = "/getDeviceMark",method = RequestMethod.POST)
    public Object getDeviceMark(String token,String createTime,String sign,String language,String projectId){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("projectId",projectId);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo=userCache.retrieve(token);
            List<VisitorDeviceMarkInfoVO> markList= iAppDeviceServiceClient.getDeviceMark(userInfo.getUserId(),projectId);
            JSONObject js = new JSONObject();
            js.put("markAry",markList);

            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode,js);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】获取当前用户的设备标签失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      删除设备标签
     * </desc>
     *
     * @param token
     * @param projectId 项目编号
     * @param markId 标签ID
     * @return
     * @author Juguang.S
     * @createDate 2019/09/03
     */
    @ResponseBody
    @RequestMapping(value = "/deleteDeviceMark",method = RequestMethod.POST)
    @LoggerInfo(operateDesc = LogDescConstant.DELETE_DEVEICE_MARKS_INFO)
    public Object deleteDeviceMark(String token,String createTime,String sign,String language,String projectId,String markId){
        MessageVO messageVO;
        try{
            boolean flag = StringUtils.isNotBlank(createTime);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
                createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
                language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
                projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
                markId = request.getAttribute("markId") == null ? null : request.getAttribute("markId").toString();
            }
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("projectId",projectId);
            params.put("markId",markId);
            //验证签名
            if (flag) {
                if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            } else {
                if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                    ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode():AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                    return new MessageVO(errorCode);
                }
            }
            if(StringUtils.isEmpty(projectId) || StringUtils.isEmpty(markId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iAppDeviceServiceClient.deleteDeviceMark(markId);
            ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.SUCCESS.getErrorCode():BaseErrorCodeEnumEN.SUCCESS.getErrorCode();
            messageVO = new MessageVO(errorCode);
        }catch ( Exception e){
            throw new DataAccessException("【APP_首页版块】删除设备标签失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      单楼层呼梯（内呼）
     * <desc/>
     *
     * @param token
     * @param deviceUnique
     * @param logicalFloor
     * @return
     * @author Jiaqi.X
     * @createDate 2019/08/29
     */
    @LoggerInfo(operateDesc = LogDescConstant.IN_CALL_ELEVATOR)
    @RequestMapping(value = "/inCall",method = RequestMethod.POST)
    @ResponseBody
    public Object inCall(String token,String deviceUnique,String logicalFloor,String correlationId,String language,String createTime,String sign) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            deviceUnique=request.getAttribute("deviceUnique")==null?null:request.getAttribute("deviceUnique").toString();
            logicalFloor=request.getAttribute("logicalFloor")==null?null:request.getAttribute("logicalFloor").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            correlationId = request.getAttribute("correlationId") == null ? null : request.getAttribute("correlationId").toString();
            language = request.getAttribute("language") == null ? null : request.getAttribute("language").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("deviceUnique",deviceUnique);
            params.put("logicalFloor",logicalFloor);
            params.put("language",language);
            //验证签名
            if(!Md5EncryptUtil.checkAppSignValue(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(deviceUnique) || StringUtils.isBlank(logicalFloor)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //判断是否开启了非标外呼
//            if(iAppProjectServiceClient.checkProjectBlueToothCall(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique)) > 0){
//                return new MessageVO(AppErrorCodeEnum.CLOUD_OUT_IN_CALL_ERROR.getErrorCode());
//            }
            CloudElevatorVO vo = iAppDeviceServiceClient.getCallElevatorInfo(deviceUnique);
            //判断当前设备是否在线，如不在线返回失败
            String isOnline = iIotServerServiceClient.batchGetDeviceState(vo.getIotProductKey(),deviceUnique);
            if(isOnline ==null || (isOnline != null && !isOnline.equals(IotDeviceStatusEnum.ONLINE.getType()))){
                return new MessageVO(AppErrorCodeEnum.CLOUD_ELEVATOR_OPEN_ERROR.getErrorCode());
            }
            //获取真实楼层
            Map<String,Object> floor = iAppDeviceServiceClient.getFloorNumAndNaturalFloorByLogicFloor(logicalFloor,
                    deviceUnique);
            if(floor ==null || floor.get("floors") ==null || floor.get("naturals") == null){
                return new MessageVO(AppErrorCodeEnum.ELEVATOR_FLOOR_ERROR.getErrorCode());
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfoPo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(token));
            //调用IOT呼梯
            iAppDeviceServiceClient.openOrAutoRegister(deviceUnique,
                    CloudElevatorSourceEnum.ITLONG_CLOUD_ELEVATOR.getDescription(),
                    floor.get("floors").toString(),  CloudElevatorCallTypeEnum.IN.getType(),0, CallElevatorSourceTypeEnum.MINIPROGRAM.getType(), null, userInfoPo.getUserId());

            String finalToken = token;
            String finalDeviceUnique = deviceUnique;
            String finalCorrelationId = correlationId;
            new Thread(()->{
                try {
                    //此处休眠5秒是便于蓝牙呼梯通行记录的上传
                    Thread.sleep(5000);
                    //装配保存通行记录对象
                    AppUserCacheVO userInfo=userCache.retrieve(finalToken);
                    AppCallLiftSaveDTO saveDTO = new AppCallLiftSaveDTO();
                    saveDTO.setUserId(userInfo.getUserId());
                    saveDTO.setDeviceUnique(finalDeviceUnique);
                    saveDTO.setProjectId(finalDeviceUnique.substring(0,8));
                    saveDTO.setMark(1);
                    saveDTO.setCorrelationId(finalCorrelationId);
                    saveDTO.setSource(1);
                    iAppHomeServiceClient.saveCallLiftRecord(saveDTO);
                } catch (Exception e) {
                    throw new DataAccessException("【APP_首页版块】单楼层呼梯", e);
                }
            }).start();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】单楼层呼梯", e);
        }
    }

    /**
     * <desc>
     *      预约呼梯仅供于前海嘉里非标项目调用。
     * <desc/>
     *
     * @param  callLiftDTO1 呼梯数据对象
     * @param  sign 凭证
     * @return
     * @author Juguang.S
     * @createDate 2020-03-11
     */
    @LoggerInfo(operateDesc = LogDescConstant.CALL_ELEVATOR)
    @RequestMapping(value = "/cloudCallLiftByNonStandard",method = RequestMethod.POST)
    @ResponseBody
    public Object callLiftByNonStandard(AppCallLiftDTO callLiftDTO1, String sign) {
        MessageVO messageVO;
        try {
            boolean flag = StringUtils.isNotBlank(sign);
            if (!flag) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                callLiftDTO1 = HttpProtocolUtil.parseRequestParamToDTO(AppCallLiftDTO.class, request);
                sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            }
            AppCallLiftDTO callLiftDTO = callLiftDTO1;
            //验证签名
            if (flag) {
                if (!Md5EncryptUtil.checkAppSign(callLiftDTO, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            } else {
                if (!Md5EncryptUtil.checkAppSignValue(callLiftDTO, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                    return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
                }
            }
            //判断设备唯一编号
            if (StringUtils.isBlank(callLiftDTO.getDeviceUnique())) {
                return new MessageVO(AppErrorCodeEnum.DEVICE_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            CloudElevatorVO vo = iAppDeviceServiceClient.getCallElevatorInfo(callLiftDTO.getDeviceUnique());

            //判断楼层
            Map result = StringHandlerUtil.checkFloor(callLiftDTO.getFromId(), callLiftDTO.getToId(), PlatformConstants.MAX_FLOOR_NUM);
            if (!"0".equals(result.get("code").toString())) {
                return new MessageVO(AppErrorCodeEnum.ELEVATOR_FLOOR_ERROR.getErrorCode(), result.get("message"));
            }
            //从缓存中获取用户信息
            AppUserCacheVO userInfo = (AppUserCacheVO) StringHandlerUtil.formatString(userCache.retrieve(callLiftDTO.getToken()));
            //电梯设备信息
            List<AppFloorDevicesVO> floors = iAppDeviceServiceClient.getFloorDevices(userInfo.getUserId(), userInfo.getCurrentProjectId(), 0);
            List<String> floorDeviceUniqueList = new ArrayList<>();
            for (AppFloorDevicesVO appFloorDevicesVO : floors) {
                floorDeviceUniqueList.add(appFloorDevicesVO.getDeviceUnique());
            }

            //取真实楼层
            AppElevatorFloorSimpleVO simpleVO = iAppHomeServiceClient.getRealFloorInfo(callLiftDTO.getDeviceUnique(), callLiftDTO.getFromId(), callLiftDTO.getToId());
            if (simpleVO == null) {
                LOG.info(String.format("【首页_预约呼梯】楼层号信息有误，设备号：%s 出发楼层：s%  目标楼层：s%", callLiftDTO.getDeviceUnique(), callLiftDTO.getFromId(), callLiftDTO.getToId()));
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
            }

            //调用IOT呼梯
            Map<String,String> map = iAppDeviceServiceClient.cloudElevatorCallByNonStandard(callLiftDTO.getDeviceUnique(), callLiftDTO.getFromId(),callLiftDTO.getToId(), userInfo.getUserId());

            if(map!=null && map.containsKey("errorMsg")){
                if("1".equals(map.get("errorMsg"))){
                    return new MessageVO(AppErrorCodeEnum.CLOUD_CONNING_SMARTCARD_ERR.getErrorCode());
                }
                if("2".equals(map.get("errorMsg"))){
                    return new MessageVO(AppErrorCodeEnum.SMARTCARD_ERR.getErrorCode(), map.get("message"));
                }
            }

            Map<String, Object> returnData = new HashMap<>();
            returnData.put("deviceUnique", map.get("deviceUnique"));
            returnData.put("deviceName", map.get("deviceName"));
            returnData.put("fromId", callLiftDTO.getFromId());
            returnData.put("fromNum", simpleVO.getFromFloor());
            returnData.put("toId", callLiftDTO.getToId());
            returnData.put("toNum", simpleVO.getToFloor());
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), returnData);
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】前海嘉里非标项目预约呼梯失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      通过城市id或城市名称获取项目信息和区名称
     * </desc>
     *
     * @param appGetProjectDTO app获取项目和区信息传参DTO
     * @param request
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/6
     */
    @RequestMapping(value = "getDistinctProject", method = RequestMethod.POST)
    public Object getProjectByCityId(AppGetProjectDTO appGetProjectDTO, HttpServletRequest request){
        try {
            appGetProjectDTO = HttpProtocolUtil.parseRequestParamToDTO(AppGetProjectDTO.class, request);

            Map<String, String> params = new HashMap<>();
            params.put("cityId", appGetProjectDTO.getCityId());
            params.put("language", appGetProjectDTO.getLanguage());
            params.put("createTime", appGetProjectDTO.getCreateTime());
            if (!Md5EncryptUtil.checkAppSignValue(params, appGetProjectDTO.getSign(), APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(appGetProjectDTO.getCityId())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<AppDistinctProjectVO> distinctProjectVOList =  iAppProjectServiceClient.getProjectsInCity(appGetProjectDTO);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("districts", distinctProjectVOList);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        }catch (Exception e){
            throw new DataAccessException("【App_首页板块getProjectByCityId】通过城市id或城市名称获取项目信息和区名称失败", e);
        }
    }

    /**
     * <desc>
     *      选择项目
     * </desc>
     *
     * @param appGetProjectDTO app选择项目传参DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/6
     */
    @LoggerInfo(operateDesc = LogDescConstant.USER_PROJECT_SAVE_LOG_DESC)
    @RequestMapping(value = "selectProject", method = RequestMethod.POST)
    public Object selectProject(AppGetProjectDTO appGetProjectDTO,  HttpServletRequest request){
        try {
            appGetProjectDTO = HttpProtocolUtil.parseRequestParamToDTO(AppGetProjectDTO.class, request);
            Map<String, String> params = new HashMap<>();
            params.put("projectId", appGetProjectDTO.getProjectId());
            params.put("language", appGetProjectDTO.getLanguage());
            params.put("createTime", appGetProjectDTO.getCreateTime());
            if (!Md5EncryptUtil.checkAppSignValue(params, appGetProjectDTO.getSign(), APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            AppUserCacheVO userCacheVO = userCache.retrieve(appGetProjectDTO.getToken());
            appGetProjectDTO.setUserId(userCacheVO.getUserId());
            appGetProjectDTO.setPhoneNum(userCacheVO.getPhoneNo());
            iAppProjectServiceClient.saveUserProject(appGetProjectDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【App_首页板块selectProject】选择项目失败", e);
        }
    }

    /**
     * <desc>
     *      社区园区搜索
     * </desc>
     *
     * @param appGetProjectDTO 项目搜索传参DTO
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/6
     */
    @RequestMapping(value = "communitySearch", method = RequestMethod.POST)
    public Object communitySearch(AppGetProjectDTO appGetProjectDTO, HttpServletRequest request){
        try {
            appGetProjectDTO = HttpProtocolUtil.parseRequestParamToDTO(AppGetProjectDTO.class, request);
            Map<String, String> params = new HashMap<>();
            params.put("projectName", appGetProjectDTO.getProjectName());
            params.put("language", appGetProjectDTO.getLanguage());
            params.put("createTime", appGetProjectDTO.getCreateTime());
            if (!Md5EncryptUtil.checkAppSignValue(params, appGetProjectDTO.getSign(), APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            List<Map<String, Object>> projectList = iAppProjectServiceClient.getProjectByProjectName(appGetProjectDTO.getProjectName());
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), projectList);
        }catch (Exception e){
            throw new DataAccessException("【App_首页板块communitySearch】搜索项目失败", e);
        }
    }

    /**
     * <desc>
     *      删除用户项目
     * </desc>
     *
     * @param appGetProjectDTO 删除项目传参DTO
     * @param request
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/7
     */
    @LoggerInfo(operateDesc = LogDescConstant.USER_PROJECT_REMOVE_LOG_DESC)
    @RequestMapping(value = "deleteProject", method =  RequestMethod.POST)
    public Object deleteUserProject(AppGetProjectDTO appGetProjectDTO, HttpServletRequest request){
        try {
            appGetProjectDTO = HttpProtocolUtil.parseRequestParamToDTO(AppGetProjectDTO.class, request);
            Map<String, String> params = new HashMap<>();
            params.put("projectId", appGetProjectDTO.getProjectId());
            params.put("language", appGetProjectDTO.getLanguage());
            params.put("createTime", appGetProjectDTO.getCreateTime());
            if (!Md5EncryptUtil.checkAppSignValue(params, appGetProjectDTO.getSign(), APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(appGetProjectDTO.getProjectId())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppUserCacheVO userCacheVO = userCache.retrieve(appGetProjectDTO.getToken());
            appGetProjectDTO.setUserId(userCacheVO.getUserId());
            return iAppProjectServiceClient.deleteUserProject(appGetProjectDTO);
        }catch (Exception e){
            throw new DataAccessException("【App_首页板块删除项目deleteProject】删除项目失败", e);
        }
    }

    /**
     * <desc>
     *      获取项目下的用户类型列表
     * </desc>
     *
     * @param appGetProjectDTO
     * @param request
     * @return
     * @Author Zhu.yj
     * @createDate  2021/5/14
     */
    @PostMapping("getUserRoleList")
    public Object getUserRoleList(AppGetProjectDTO appGetProjectDTO, HttpServletRequest request){
        try{
            appGetProjectDTO = HttpProtocolUtil.parseRequestParamToDTO(AppGetProjectDTO.class, request);
            Map<String, String> params = new HashMap<>();
            params.put("projectId", appGetProjectDTO.getProjectId());
            params.put("language", appGetProjectDTO.getLanguage());
            params.put("createTime", appGetProjectDTO.getCreateTime());
            if (!Md5EncryptUtil.checkAppSignValue(params, appGetProjectDTO.getSign(), APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(appGetProjectDTO.getProjectId())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<Map<String, Object>> userRoleList = iAppProjectServiceClient.getProjectUserRoleList(appGetProjectDTO.getProjectId());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("roleList", userRoleList);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), jsonObject);
        }catch (Exception e){
            throw new DataAccessException("【App_首页板块获取项目下的用户类型getUserRoleList】获取项目下的用户类型失败", e);
        }
    }
}
